GCC(1)
๐ธ GCC(1) ยท GNU ๐ธ
Part 1 of 107. Bestie, this is the opening chunk, so the rest is coming! ๐
โจ NAME โจ
gcc - GNU project C and C++ compiler. This is the GNU project's C and C++ compiler, the main character of this whole page ๐.
โจ SYNOPSIS โจ
Okay, here's how the command is shaped:
gcc [-c|-S|-E] [-std=standard]
[-g] [-pg] [-Olevel]
[-Wwarn...] [-Wpedantic]
[-Idir...] [-Ldir...]
[-Dmacro[=defn]...] [-Umacro]
[-foption...] [-mmachine-option...]
[-o outfile] [@file] infile...
Only the most useful options made the cut here, so check below for the rest ๐. g++ accepts mostly the same options as gcc. ๐ง
โจ DESCRIPTION โจ
Okay so when you run GCC, it normally goes through the whole glow-up: preprocessing, compilation, assembly and linking ๐
. The "overall options" let you stop the process at an intermediate stage. For example, -c tells it not to run the linker, so the output is just the object files spat out by the assembler ๐ฆ.
Other options get passed along to one or more stages. Some control the preprocessor, some control the compiler itself, and yet others control the assembler and linker. Most of those last ones aren't documented here, because you almost never need them ๐ซถ.
Most of the command-line options are useful for C programs. When an option only matters for another language (usually C++), the explanation will say so explicitly. If an option's description doesn't mention a source language, you can use it with all supported languages โจ.
The usual way to run GCC is the executable called gcc, or machine-gcc when cross-compiling, or machine-gcc-version if you want a specific version of GCC. When you compile C++ programs, invoke GCC as g++ instead ๐.
The gcc program takes options and file names as operands. Lots of options have multi-letter names, so you can't bunch up single-letter options together. -dv is very different from -d -v, so don't get it twisted ๐.
You can mix options and other arguments, and for the most part the order doesn't matter. Order does matter when you use several options of the same kind. For example, if you specify -L more than once, the directories get searched in the order you gave them. The placement of the -l option is also significant ๐.
Lots of options have long names that start with -f or with -W---for. For example, -fmove-loop-invariants, -Wformat and so on ๐. Most of these come in both positive and negative forms, and the negative form of -ffoo is -fno-foo. This manual only documents one of the two forms, whichever one is not the default ๐ฅ.
Some options take one or more arguments, usually separated from the option name by a space or by the equals sign (=). Unless the docs say otherwise, an argument can be either numeric or a string. Numeric arguments are typically small unsigned decimal or hexadecimal integers, and hexadecimal arguments must begin with the 0x prefix ๐.
Arguments to options that set some kind of size threshold can be arbitrarily large decimal or hexadecimal integers, followed by a byte size suffix that designates a multiple of bytes. The suffixes are kB and KiB for kilobyte and kibibyte, MB and MiB for megabyte and mebibyte, GB and GiB for gigabyte and gigibyte, and so on ๐ธ. The text calls these arguments byte-size from here on. For the full list and the actual explanation of the binary and decimal byte size prefixes, go check the NIST, IEC, and other relevant national and international standards โญ.
โจ OPTIONS โจ
๐ฆ Option Summary ๐ฆ
Here's the full tea on every option, grouped by type. The explanations come in the following sections ๐.
๐ธ Overall Options ๐ธ
-c -S -E -o file -x language -v -### --help[=class[,...]]
--target-help --version -pass-exit-codes -pipe -specs=file
-wrapper @file -ffile-prefix-map=old=new -fplugin=file
-fplugin-arg-name=arg -fdump-ada-spec[-slim] -fada-spec-parent=unit
-fdump-go-spec=file
๐ C Language Options ๐
-ansi -std=standard -fgnu89-inline
-fpermitted-flt-eval-methods=standard -aux-info filename
-fallow-parameterless-variadic-functions -fno-asm -fno-builtin
-fno-builtin-function -fgimple -fhosted -ffreestanding -fopenacc
-fopenacc-dim=geom -fopenmp -fopenmp-simd -fms-extensions
-fplan9-extensions -fsso-struct=endianness -fallow-single-precision
-fcond-mismatch -flax-vector-conversions -fsigned-bitfields
-fsigned-char -funsigned-bitfields -funsigned-char
๐ C++ Language Options ๐
-fabi-version=n -fno-access-control -faligned-new=n
-fargs-in-order=n -fchar8_t -fcheck-new -fconstexpr-depth=n
-fconstexpr-cache-depth=n -fconstexpr-loop-limit=n
-fconstexpr-ops-limit=n -fno-elide-constructors
-fno-enforce-eh-specs -fno-gnu-keywords -fno-implicit-templates
-fno-implicit-inline-templates -fno-implement-inlines
-fms-extensions -fnew-inheriting-ctors -fnew-ttp-matching
-fno-nonansi-builtins -fnothrow-opt -fno-operator-names
-fno-optional-diags -fpermissive -fno-pretty-templates -fno-rtti
-fsized-deallocation -ftemplate-backtrace-limit=n -ftemplate-depth=n
-fno-threadsafe-statics -fuse-cxa-atexit -fno-weak -nostdinc++
-fvisibility-inlines-hidden -fvisibility-ms-compat
-fext-numeric-literals -Wabi-tag -Wcatch-value -Wcatch-value=n
-Wno-class-conversion -Wclass-memaccess -Wcomma-subscript
-Wconditionally-supported -Wno-conversion-null -Wctor-dtor-privacy
-Wno-delete-incomplete -Wdelete-non-virtual-dtor -Wdeprecated-copy
-Wdeprecated-copy-dtor -Weffc++ -Wextra-semi
-Wno-inaccessible-base -Wno-inherited-variadic-ctor
-Wno-init-list-lifetime -Wno-invalid-offsetof -Wno-literal-suffix
-Wmismatched-tags -Wmultiple-inheritance -Wnamespaces -Wnarrowing
-Wnoexcept -Wnoexcept-type -Wnon-virtual-dtor -Wpessimizing-move
-Wno-placement-new -Wplacement-new=n -Wredundant-move
-Wredundant-tags -Wreorder -Wregister -Wstrict-null-sentinel
-Wno-subobject-linkage -Wtemplates -Wno-non-template-friend
-Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions
-Wsign-promo -Wsized-deallocation -Wsuggest-final-methods
-Wsuggest-final-types -Wsuggest-override -Wno-terminate
-Wuseless-cast -Wvirtual-inheritance -Wno-virtual-move-assign
-Wvolatile -Wzero-as-null-pointer-constant
๐ Objective-C and Objective-C++ Language Options ๐
-fconstant-string-class=class-name -fgnu-runtime -fnext-runtime
-fno-nil-receivers -fobjc-abi-version=n -fobjc-call-cxx-cdtors
-fobjc-direct-dispatch -fobjc-exceptions -fobjc-gc -fobjc-nilcheck
-fobjc-std=objc1 -fno-local-ivars
-fivar-visibility=[public|protected|private|package]
-freplace-objc-classes -fzero-link -gen-decls -Wassign-intercept
-Wno-property-assign-default -Wno-protocol -Wselector
-Wstrict-selector-match -Wundeclared-selector
๐ซง Diagnostic Message Formatting Options ๐ซง
-fmessage-length=n -fdiagnostics-show-location=[once|every-line]
-fdiagnostics-color=[auto|never|always]
-fdiagnostics-urls=[auto|never|always]
-fdiagnostics-format=[text|json] -fno-diagnostics-show-option
-fno-diagnostics-show-caret -fno-diagnostics-show-labels
-fno-diagnostics-show-line-numbers -fno-diagnostics-show-cwe
-fdiagnostics-minimum-margin-width=width
-fdiagnostics-parseable-fixits -fdiagnostics-generate-patch
-fdiagnostics-show-template-tree -fno-elide-type
-fdiagnostics-path-format=[none|separate-events|inline-events]
-fdiagnostics-show-path-depths -fno-show-column
โจ Warning Options โจ
Okay bestie, this is the whole warning squad ๐จ Every flag is kept whole and copy-paste ready ๐
-fsyntax-only -fmax-errors=n -Wpedantic -pedantic-errors -w
-Wextra -Wall -Wabi=n -Waddress -Wno-address-of-packed-member
-Waggregate-return -Walloc-size-larger-than=byte-size -Walloc-zero
-Walloca -Walloca-larger-than=byte-size
-Wno-aggressive-loop-optimizations -Warith-conversion -Warray-bounds
-Warray-bounds=n -Wno-attributes -Wattribute-alias=n
-Wno-attribute-alias -Wno-attribute-warning -Wbool-compare
-Wbool-operation -Wno-builtin-declaration-mismatch
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat
-Wc11-c2x-compat -Wc++-compat -Wc++11-compat -Wc++14-compat
-Wc++17-compat -Wc++20-compat -Wcast-align -Wcast-align=strict
-Wcast-function-type -Wcast-qual -Wchar-subscripts -Wclobbered
-Wcomment -Wconversion -Wno-coverage-mismatch -Wno-cpp
-Wdangling-else -Wdate-time -Wno-deprecated
-Wno-deprecated-declarations -Wno-designated-init
-Wdisabled-optimization -Wno-discarded-array-qualifiers
-Wno-discarded-qualifiers -Wno-div-by-zero -Wdouble-promotion
-Wduplicated-branches -Wduplicated-cond -Wempty-body
-Wno-endif-labels -Wenum-compare -Wenum-conversion -Werror
-Werror=* -Wexpansion-to-defined -Wfatal-errors -Wfloat-conversion
-Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul
-Wno-format-extra-args -Wformat-nonliteral -Wformat-overflow=n
-Wformat-security -Wformat-signedness -Wformat-truncation=n
-Wformat-y2k -Wframe-address -Wframe-larger-than=byte-size
-Wno-free-nonheap-object -Wno-hsa -Wno-if-not-aligned
-Wno-ignored-attributes -Wignored-qualifiers
-Wno-incompatible-pointer-types -Wimplicit -Wimplicit-fallthrough
-Wimplicit-fallthrough=n -Wno-implicit-function-declaration
-Wno-implicit-int -Winit-self -Winline -Wno-int-conversion
-Wint-in-bool-context -Wno-int-to-pointer-cast
-Wno-invalid-memory-model -Winvalid-pch -Wjump-misses-init
-Wlarger-than=byte-size -Wlogical-not-parentheses -Wlogical-op
-Wlong-long -Wno-lto-type-mismatch -Wmain -Wmaybe-uninitialized
-Wmemset-elt-size -Wmemset-transposed-args -Wmisleading-indentation
-Wmissing-attributes -Wmissing-braces -Wmissing-field-initializers
-Wmissing-format-attribute -Wmissing-include-dirs
-Wmissing-noreturn -Wno-missing-profile -Wno-multichar
-Wmultistatement-macros -Wnonnull -Wnonnull-compare
-Wnormalized=[none|id|nfc|nfkc] -Wnull-dereference -Wno-odr
-Wopenmp-simd -Wno-overflow -Woverlength-strings
-Wno-override-init-side-effects -Wpacked
-Wno-packed-bitfield-compat -Wpacked-not-aligned -Wpadded
-Wparentheses -Wno-pedantic-ms-format -Wpointer-arith
-Wno-pointer-compare -Wno-pointer-to-int-cast -Wno-pragmas
-Wno-prio-ctor-dtor -Wredundant-decls -Wrestrict
-Wno-return-local-addr -Wreturn-type -Wno-scalar-storage-order
-Wsequence-point -Wshadow -Wshadow=global -Wshadow=local
-Wshadow=compatible-local -Wno-shadow-ivar -Wno-shift-count-negative
-Wno-shift-count-overflow -Wshift-negative-value
-Wno-shift-overflow -Wshift-overflow=n -Wsign-compare
-Wsign-conversion -Wno-sizeof-array-argument -Wsizeof-pointer-div
-Wsizeof-pointer-memaccess -Wstack-protector -Wstack-usage=byte-size
-Wstrict-aliasing -Wstrict-aliasing=n -Wstrict-overflow
-Wstrict-overflow=n -Wstring-compare -Wstringop-overflow=n
-Wno-stringop-truncation
-Wsuggest-attribute=[pure|const|noreturn|format|malloc] -Wswitch
-Wno-switch-bool -Wswitch-default -Wswitch-enum
-Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand
-Wsystem-headers -Wtautological-compare -Wtrampolines -Wtrigraphs
-Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas
-Wunsuffixed-float-constants -Wunused -Wunused-but-set-parameter
-Wunused-but-set-variable -Wunused-const-variable
-Wunused-const-variable=n -Wunused-function -Wunused-label
-Wunused-local-typedefs -Wunused-macros -Wunused-parameter
-Wno-unused-result -Wunused-value -Wunused-variable -Wno-varargs
-Wvariadic-macros -Wvector-operation-performance -Wvla
-Wvla-larger-than=byte-size -Wno-vla-larger-than
-Wvolatile-register-var -Wwrite-strings -Wzero-length-bounds
๐ Static Analyzer Options ๐
Ooh, the static analyzer squad ๐ต๏ธโโ๏ธ Here's the full lineup, no cuts:
-fanalyzer -fanalyzer-call-summaries -fanalyzer-checker=name
-fanalyzer-fine-grained -fanalyzer-state-merge
-fanalyzer-state-purge -fanalyzer-transitivity
-fanalyzer-verbose-edges -fanalyzer-verbose-state-changes
-fanalyzer-verbosity=level -fdump-analyzer -fdump-analyzer-stderr
-fdump-analyzer-callgraph -fdump-analyzer-exploded-graph
-fdump-analyzer-exploded-nodes -fdump-analyzer-exploded-nodes-2
-fdump-analyzer-exploded-nodes-3 -fdump-analyzer-state-purge
-fdump-analyzer-supergraph -Wno-analyzer-double-fclose
-Wno-analyzer-double-free -Wno-analyzer-exposure-through-output-file
-Wno-analyzer-file-leak -Wno-analyzer-free-of-non-heap
-Wno-analyzer-malloc-leak -Wno-analyzer-null-argument
-Wno-analyzer-null-dereference -Wno-analyzer-possible-null-argument
-Wno-analyzer-possible-null-dereference
-Wno-analyzer-stale-setjmp-buffer -Wno-analyzer-tainted-array-index
-Wanalyzer-too-complex
-Wno-analyzer-unsafe-call-within-signal-handler
-Wno-analyzer-use-after-free
-Wno-analyzer-use-of-pointer-in-stale-stack-frame
-Wno-analyzer-use-of-uninitialized-value
๐ธ C and Objective-C-only Warning Options ๐ธ
Next up, the C and Objective-C-only crew ๐ท These are kept exactly as they are:
-Wbad-function-cast -Wmissing-declarations -Wmissing-parameter-type
-Wmissing-prototypes -Wnested-externs -Wold-style-declaration
-Wold-style-definition -Wstrict-prototypes -Wtraditional
-Wtraditional-conversion -Wdeclaration-after-statement
-Wpointer-sign
๐ Debugging Options ๐
And last but not least, the debugging options ๐ง Bug hunting era, let's go ๐ฅ
-g -glevel -gdwarf -gdwarf-version -ggdb -grecord-gcc-switches
-gno-record-gcc-switches -gstabs -gstabs+ -gstrict-dwarf
-gno-strict-dwarf -gas-loc-support -gno-as-loc-support
-gas-locview-support -gno-as-locview-support -gcolumn-info
-gno-column-info -gstatement-frontiers -gno-statement-frontiers
-gvariable-location-views -gno-variable-location-views
-ginternal-reset-location-views -gno-internal-reset-location-views
-ginline-points -gno-inline-points -gvms -gxcoff -gxcoff+
-gz[=type] -gsplit-dwarf -gdescribe-dies -gno-describe-dies
-fdebug-prefix-map=old=new -fdebug-types-section
-fno-eliminate-unused-debug-types -femit-struct-debug-baseonly
-femit-struct-debug-reduced -femit-struct-debug-detailed[=spec-list]
-fno-eliminate-unused-debug-symbols -femit-class-debug-always
-fno-merge-debug-strings -fno-dwarf2-cfi-asm -fvar-tracking
-fvar-tracking-assignments
โจ Optimization Options โจ
okay bestie, this list is HUGE ๐ญ๐ฅ the page just drops the names here with no notes, so these are the flags in their full glory ๐
-faggressive-loop-optimizations -falign-functions[=n[:m:[n2[:m2]]]]
-falign-jumps[=n[:m:[n2[:m2]]]] -falign-labels[=n[:m:[n2[:m2]]]]
-falign-loops[=n[:m:[n2[:m2]]]] -fno-allocation-dce
-fallow-store-data-races -fassociative-math -fauto-profile
-fauto-profile[=path] -fauto-inc-dec -fbranch-probabilities
-fcaller-saves -fcombine-stack-adjustments -fconserve-stack
-fcompare-elim -fcprop-registers -fcrossjumping -fcse-follow-jumps
-fcse-skip-blocks -fcx-fortran-rules -fcx-limited-range
-fdata-sections -fdce -fdelayed-branch
-fdelete-null-pointer-checks -fdevirtualize
-fdevirtualize-speculatively -fdevirtualize-at-ltrans -fdse
-fearly-inlining -fipa-sra -fexpensive-optimizations
-ffat-lto-objects -ffast-math -ffinite-math-only -ffloat-store
-fexcess-precision=style -ffinite-loops -fforward-propagate
-ffp-contract=style -ffunction-sections -fgcse -fgcse-after-reload
-fgcse-las -fgcse-lm -fgraphite-identity -fgcse-sm
-fhoist-adjacent-loads -fif-conversion -fif-conversion2
-findirect-inlining -finline-functions
-finline-functions-called-once -finline-limit=n
-finline-small-functions -fipa-cp -fipa-cp-clone -fipa-bit-cp
-fipa-vrp -fipa-pta -fipa-profile -fipa-pure-const
-fipa-reference -fipa-reference-addressable -fipa-stack-alignment
-fipa-icf -fira-algorithm=algorithm -flive-patching=level
-fira-region=region -fira-hoist-pressure -fira-loop-pressure
-fno-ira-share-save-slots -fno-ira-share-spill-slots
-fisolate-erroneous-paths-dereference
-fisolate-erroneous-paths-attribute -fivopts
-fkeep-inline-functions -fkeep-static-functions
-fkeep-static-consts -flimit-function-alignment
-flive-range-shrinkage -floop-block -floop-interchange
-floop-strip-mine -floop-unroll-and-jam -floop-nest-optimize
-floop-parallelize-all -flra-remat -flto -flto-compression-level
-flto-partition=alg -fmerge-all-constants -fmerge-constants
-fmodulo-sched -fmodulo-sched-allow-regmoves -fmove-loop-invariants
-fno-branch-count-reg -fno-defer-pop -fno-fp-int-builtin-inexact
-fno-function-cse -fno-guess-branch-probability -fno-inline
-fno-math-errno -fno-peephole -fno-peephole2
-fno-printf-return-value -fno-sched-interblock -fno-sched-spec
-fno-signed-zeros -fno-toplevel-reorder -fno-trapping-math
-fno-zero-initialized-in-bss -fomit-frame-pointer
-foptimize-sibling-calls -fpartial-inlining -fpeel-loops
-fpredictive-commoning -fprefetch-loop-arrays -fprofile-correction
-fprofile-use -fprofile-use=path -fprofile-partial-training
-fprofile-values -fprofile-reorder-functions -freciprocal-math
-free -frename-registers -freorder-blocks
-freorder-blocks-algorithm=algorithm -freorder-blocks-and-partition
-freorder-functions -frerun-cse-after-loop
-freschedule-modulo-scheduled-loops -frounding-math
-fsave-optimization-record -fsched2-use-superblocks
-fsched-pressure -fsched-spec-load -fsched-spec-load-dangerous
-fsched-stalled-insns-dep[=n] -fsched-stalled-insns[=n]
-fsched-group-heuristic -fsched-critical-path-heuristic
-fsched-spec-insn-heuristic -fsched-rank-heuristic
-fsched-last-insn-heuristic -fsched-dep-count-heuristic
-fschedule-fusion -fschedule-insns -fschedule-insns2
-fsection-anchors -fselective-scheduling -fselective-scheduling2
-fsel-sched-pipelining -fsel-sched-pipelining-outer-loops
-fsemantic-interposition -fshrink-wrap -fshrink-wrap-separate
-fsignaling-nans -fsingle-precision-constant
-fsplit-ivs-in-unroller -fsplit-loops -fsplit-paths
-fsplit-wide-types -fsplit-wide-types-early -fssa-backprop
-fssa-phiopt -fstdarg-opt -fstore-merging -fstrict-aliasing
-fthread-jumps -ftracer -ftree-bit-ccp -ftree-builtin-call-dce
-ftree-ccp -ftree-ch -ftree-coalesce-vars -ftree-copy-prop
-ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop
-ftree-fre -fcode-hoisting -ftree-loop-if-convert -ftree-loop-im
-ftree-phiprop -ftree-loop-distribution
-ftree-loop-distribute-patterns -ftree-loop-ivcanon
-ftree-loop-linear -ftree-loop-optimize -ftree-loop-vectorize
-ftree-parallelize-loops=n -ftree-pre -ftree-partial-pre
-ftree-pta -ftree-reassoc -ftree-scev-cprop -ftree-sink
-ftree-slsr -ftree-sra -ftree-switch-conversion -ftree-tail-merge
-ftree-ter -ftree-vectorize -ftree-vrp -funconstrained-commons
-funit-at-a-time -funroll-all-loops -funroll-loops
-funsafe-math-optimizations -funswitch-loops -fipa-ra
-fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb
-fwhole-program -fwpa -fuse-linker-plugin --param name=value -O
-O0 -O1 -O2 -O3 -Os -Ofast -Og
โจ Program Instrumentation Options โจ
the instrumentation crew is up next ๐ง same deal, just the names, served fresh ๐
-p -pg -fprofile-arcs --coverage -ftest-coverage
-fprofile-abs-path -fprofile-dir=path -fprofile-generate
-fprofile-generate=path -fprofile-note=path
-fprofile-prefix-path=path -fprofile-update=method
-fprofile-filter-files=regex -fprofile-exclude-files=regex
-fprofile-reproducible=[multithreaded|parallel-runs|serial]
-fsanitize=style -fsanitize-recover -fsanitize-recover=style
-fasan-shadow-offset=number -fsanitize-sections=s1,s2,...
-fsanitize-undefined-trap-on-error -fbounds-check
-fcf-protection=[full|branch|return|none|check] -fstack-protector
-fstack-protector-all -fstack-protector-strong
-fstack-protector-explicit -fstack-check -fstack-limit-register=reg
-fstack-limit-symbol=sym -fno-stack-limit -fsplit-stack
-fvtable-verify=[std|preinit|none] -fvtv-counts -fvtv-debug
-finstrument-functions
-finstrument-functions-exclude-function-list=sym,sym,...
-finstrument-functions-exclude-file-list=file,file,...
โจ Preprocessor Options โจ
the preprocessor is giving main character energy ๐ here's the whole cast:
-Aquestion=answer -A-question[=answer] -C -CC -Dmacro[=defn] -dD
-dI -dM -dN -dU -fdebug-cpp -fdirectives-only
-fdollars-in-identifiers -fexec-charset=charset
-fextended-identifiers -finput-charset=charset
-fmacro-prefix-map=old=new -fmax-include-depth=depth
-fno-canonical-system-headers -fpch-deps -fpch-preprocess
-fpreprocessed -ftabstop=width -ftrack-macro-expansion
-fwide-exec-charset=charset -fworking-directory -H -imacros file
-include file -M -MD -MF -MG -MM -MMD -MP -MQ -MT
-no-integrated-cpp -P -pthread -remap -traditional
-traditional-cpp -trigraphs -Umacro -undef -Wp,option
-Xpreprocessor option
โจ Assembler Options โจ
short and sweet, the assembler only has two ๐ซถ
-Wa,option -Xassembler option
โจ Linker Options โจ
the linker is the final boss ๐ and it has a LOT of options ๐
object-file-name -fuse-ld=linker -llibrary -nostartfiles
-nodefaultlibs -nolibc -nostdlib -e entry --entry=entry -pie
-pthread -r -rdynamic -s -static -static-pie -static-libgcc
-static-libstdc++ -static-libasan -static-libtsan -static-liblsan
-static-libubsan -shared -shared-libgcc -symbolic -T script
-Wl,option -Xlinker option -u symbol -z keyword
โจ Directory Options โจ
where the compiler goes looking for stuff ๐ฆ the search-path squad:
-Bprefix -Idir -I- -idirafter dir -imacros file -imultilib dir
-iplugindir=dir -iprefix file -iquote dir -isysroot dir -isystem
dir -iwithprefix dir -iwithprefixbefore dir -Ldir
-no-canonical-prefixes --no-sysroot-suffix -nostdinc -nostdinc++
--sysroot=dir
โจ Code Generation Options โจ
this is where the code gets dressed up for the machine ๐๐
-fcall-saved-reg -fcall-used-reg -ffixed-reg -fexceptions
-fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables
-fasynchronous-unwind-tables -fno-gnu-unique
-finhibit-size-directive -fcommon -fno-ident -fpcc-struct-return
-fpic -fPIC -fpie -fPIE -fno-plt -fno-jump-tables
-frecord-gcc-switches -freg-struct-return -fshort-enums
-fshort-wchar -fverbose-asm -fpack-struct[=n] -fleading-underscore
-ftls-model=model -fstack-reuse=reuse_level -ftrampolines -ftrapv
-fwrapv -fvisibility=[default|internal|hidden|protected]
-fstrict-volatile-bitfields -fsync-libcalls
โจ Developer Options โจ
for the debugging nerds ๐ค๐ this section is absolutely packed, no cap:
-dletters -dumpspecs -dumpmachine -dumpversion -dumpfullversion
-fcallgraph-info[=su,da] -fchecking -fchecking=n -fdbg-cnt-list
-fdbg-cnt=counter-value-list -fdisable-ipa-pass_name
-fdisable-rtl-pass_name -fdisable-rtl-pass-name=range-list
-fdisable-tree-pass_name -fdisable-tree-pass-name=range-list
-fdump-debug -fdump-earlydebug -fdump-noaddr -fdump-unnumbered
-fdump-unnumbered-links -fdump-final-insns[=file] -fdump-ipa-all
-fdump-ipa-cgraph -fdump-ipa-inline -fdump-lang-all
-fdump-lang-switch -fdump-lang-switch-options
-fdump-lang-switch-options=filename -fdump-passes -fdump-rtl-pass
-fdump-rtl-pass=filename -fdump-statistics -fdump-tree-all
-fdump-tree-switch -fdump-tree-switch-options
-fdump-tree-switch-options=filename -fcompare-debug[=opts]
-fcompare-debug-second -fenable-kind-pass -fenable-kind-pass=range-
list -fira-verbose=n -flto-report -flto-report-wpa
-fmem-report-wpa -fmem-report -fpre-ipa-mem-report
-fpost-ipa-mem-report -fopt-info -fopt-info-options[=file]
-fprofile-report -frandom-seed=string -fsched-verbose=n
-fsel-sched-verbose -fsel-sched-dump-cfg
-fsel-sched-pipelining-verbose -fstats -fstack-usage -ftime-report
-ftime-report-details -fvar-tracking-assignments-toggle -gtoggle
-print-file-name=library -print-libgcc-file-name
-print-multi-directory -print-multi-lib -print-multi-os-directory
-print-prog-name=program -print-search-dirs -Q -print-sysroot
-print-sysroot-headers-suffix -save-temps -save-temps=cwd
-save-temps=obj -time[=file]
โจ Machine-Dependent Options โจ
last stop on the tour ๐ธ these ones depend on the target machine, so they vary by platform ๐ง
โจ AArch64 Options โจ
-mabi=name -mbig-endian -mlittle-endian
-mgeneral-regs-only -mcmodel=tiny -mcmodel=small -mcmodel=large
-mstrict-align -mno-strict-align -momit-leaf-frame-pointer
-mtls-dialect=desc -mtls-dialect=traditional -mtls-size=size
-mfix-cortex-a53-835769 -mfix-cortex-a53-843419
-mlow-precision-recip-sqrt -mlow-precision-sqrt
-mlow-precision-div -mpc-relative-literal-loads
-msign-return-address=scope -mbranch-protection=none|standard|pac-
ret[+leaf +b-key]|bti -mharden-sls=opts -march=name -mcpu=name
-mtune=name -moverride=string -mverbose-cost-dump
-mstack-protector-guard=guard -mstack-protector-guard-reg=sysreg
-mstack-protector-guard-offset=offset -mtrack-speculation
-moutline-atomics
๐ธ Adapteva Epiphany Options ๐ธ
Okay bestie, this part is basically the roster of target-specific flags, grouped by chip. No explanations here, just the full lineup. ๐
-mhalf-reg-fileโ half-size register file ๐ง-mprefer-short-insn-regsโ short-insn regs, please ๐-mbranch-cost=numโ branch cost with a number ๐-mcmoveโ cmove, iconic โจ-mnops=numโ nops with a count ๐ซถ-msoft-cmpsfโ soft compare, single float ๐ธ-msplit-lohiโ split lo and hi ๐ฆ-mpost-incโ post-increment ๐-mpost-modifyโ post-modify ๐ฅ-mstack-offset=numโ stack offset, numbered ๐ง-mround-nearestโ round to nearest ๐-mlong-callsโ long calls ๐-mshort-callsโ short calls โญ-msmall16โ small16 vibes ๐-mfp-mode=modeโ FP mode, pick one ๐-mvect-doubleโ vectorised doubles ๐-max-vect-align=numโ max vector alignment ๐-msplit-vecmove-earlyโ split vector moves early โฉ-m1reg-regโ one reg-reg ๐ฆ
๐ AMD GCN Options ๐
-march=gpuโ pick your GPU arch ๐ฅ-mtune=gpuโ tune for a GPU ๐-mstack-size=bytesโ stack size, in bytes ๐
๐ธ ARC Options ๐ธ
-mbarrel-shifterโ barrel shifter ๐-mjli-alwaysโ JLI always โจ-mcpu=cpuโ pick a CPU ๐-mA6โ A6 energy ๐ง-mARC600โ ARC600 ๐ฆ-mA7โ A7 ๐ธ-mARC700โ ARC700 ๐-mdpfpโ double-precision FP ๐ฅ-mdpfp-compactโ compact DPFP ๐-mdpfp-fastโ fast DPFP โก-mno-dpfp-lrsrโ no DPFP LR/SR ๐-meaโ extension aux ๐ซถ-mno-mpyโ no multiply ๐-mmul32x16โ 32x16 multiply ๐-mmul64โ 64-bit multiply ๐-matomicโ atomics ๐-mnormโ normalise instruction ๐ธ-mspfpโ single-precision FP ๐ฆ-mspfp-compactโ compact SPFP ๐-mspfp-fastโ fast SPFP โก-msimdโ SIMD ๐-msoft-floatโ soft float ๐ง-mswapโ swap instruction ๐-mcrcโ CRC ๐งฎ-mdsp-packaโ DSP pack ๐ฆ-mdvbfโ DVBF ๐-mlockโ lock ๐-mmac-d16โ MAC D16 ๐-mmac-24โ MAC 24 ๐-mrtscโ RTSC โฑ๏ธ-mswapeโ swap-and-escape vibes ๐-mtelephonyโ telephony ๐-mxyโ XY memory ๐บ๏ธ-misizeโ instruction size ๐-mannotate-alignโ annotate alignment ๐ท๏ธ-marclinuxโ ARC Linux ๐ง-marclinux_profโ ARC Linux, with profiling ๐-mlong-callsโ long calls ๐-mmedium-callsโ medium calls ๐ฑ-msdataโ small data ๐๏ธ-mirq-ctrl-savedโ IRQ control saved ๐ก๏ธ-mrgf-banked-regsโ banked RGF regs ๐ฆ-mlpc-width=widthโ LPC width, set it ๐-G numโ small data threshold, numbered ๐ข-mvolatile-cacheโ volatile cache ๐ง-mtp-regno=regnoโ TP register number ๐ข-malign-callโ align calls ๐ฏ-mauto-modify-regโ auto-modify reg โ๏ธ-mbbit-peepholeโ bbit peephole ๐-mno-brccโ no BRcc ๐-mcase-vector-pcrelโ PC-relative case vectors ๐งญ-mcompact-casesiโ compact casesi ๐งฉ-mno-cond-execโ no conditional execution ๐-mearly-cbranchsiโ early cbranchsi โฉ-mexpand-adddiโ expand adddi โ-mindexed-loadsโ indexed loads ๐-mlraโ LRA ๐ง-mlra-priority-noneโ LRA priority: none ๐-mlra-priority-compactโ LRA priority: compact ๐๏ธmlra-priority-noncompactโ LRA priority: noncompact ๐งท-mmillicodeโ millicode ๐-mmixed-codeโ mixed code ๐ญ-mq-classโ q-class ๐ท๏ธ-mRcqโ Rcq ๐ ฐ๏ธ-mRcwโ Rcw ๐ ฑ๏ธ-msize-level=levelโ size level, pick one ๐-mtune=cpuโ tune for a CPU ๐๏ธ-mmultcost=numโ multiply cost, numbered ๐ฐ-mcode-density-frameโ code density frame ๐ผ๏ธ-munalign-prob-threshold=probabilityโ unaligned probability threshold ๐ฒ-mmpy-option=multoโ MPY option, multo ๐งฎ-mdiv-remโ divide and remainder โ-mcode-densityโ code density ๐๏ธ-mll64โ 64-bit long long ๐ข-mfpu=fpuโ pick an FPU ๐ง-mrf16โ 16-register file ๐งบ-mbranch-indexโ branch index ๐งญ
๐ฆ ARM Options ๐ฆ
-mapcs-frameโ APCS frame ๐ผ๏ธ-mno-apcs-frameโ no APCS frame ๐-mabi=nameโ pick an ABI ๐ท๏ธ-mapcs-stack-checkโ APCS stack check ๐-mno-apcs-stack-checkโ no APCS stack check ๐-mapcs-reentrantโ APCS reentrant ๐-mno-apcs-reentrantโ no APCS reentrant ๐-mgeneral-regs-onlyโ general regs only ๐งบ-msched-prologโ scheduled prolog ๐-mno-sched-prologโ no scheduled prolog ๐-mlittle-endianโ little endian ๐-mbig-endianโ big endian ๐-mbe8โ BE8 ๐งฉ-mbe32โ BE32 ๐งฉ-mfloat-abi=nameโ float ABI, pick one ๐ข-mfp16-format=nameโ FP16 format, pick one ๐ท๏ธ-mthumb-interworkโ Thumb interwork ๐ค-mno-thumb-interworkโ no Thumb interwork ๐-mcpu=nameโ pick a CPU ๐-march=nameโ pick an arch ๐๏ธ-mfpu=nameโ pick an FPU ๐ง-mtune=nameโ tune for a name ๐๏ธ-mprint-tune-infoโ print tune info ๐จ๏ธ-mstructure-size-boundary=nโ structure size boundary, numbered ๐-mabort-on-noreturnโ abort on noreturn ๐จ-mlong-callsโ long calls ๐-mno-long-callsโ no long calls ๐-msingle-pic-baseโ single PIC base ๐ฏ-mno-single-pic-baseโ no single PIC base ๐-mpic-register=regโ PIC register, pick one ๐-mnop-fun-dllimportโ nop for dllimport functions ๐ค-mpoke-function-nameโ poke function name ๐-mthumbโ Thumb ๐งต-marmโ ARM mode ๐ช-mflip-thumbโ flip Thumb ๐-mtpcs-frameโ TPCS frame ๐ผ๏ธ-mtpcs-leaf-frameโ TPCS leaf frame ๐-mcaller-super-interworkingโ caller super interworking ๐ค-mcallee-super-interworkingโ callee super interworking ๐ค-mtp=nameโ TP, pick a name ๐งต-mtls-dialect=dialectโ TLS dialect, pick one ๐ฃ๏ธ-mword-relocationsโ word relocations ๐งฉ-mfix-cortex-m3-ldrdโ fix Cortex-M3 LDRD ๐ฉน-munaligned-accessโ unaligned access ๐ซจ-mneon-for-64bitsโ NEON for 64-bit ops ๐ถ-mslow-flash-dataโ slow flash data ๐ข-masm-syntax-unifiedโ unified assembler syntax ๐-mrestrict-itโ restrict IT ๐ง-mverbose-cost-dumpโ verbose cost dump ๐๏ธ-mpure-codeโ pure code ๐งผ-mcmseโ CMSE ๐-mfix-cmse-cve-2021-35465โ fix CMSE CVE-2021-35465 ๐ฉน-mfdpicโ FDPIC ๐งฉ
๐ AVR Options ๐
-mmcu=mcuโ pick an MCU ๐-mabsdataโ absolute data ๐-maccumulate-argsโ accumulate args ๐งบ-mbranch-cost=costโ branch cost, with a value ๐ฐ-mcall-prologuesโ call prologues ๐-mgas-isr-prologuesโ GAS ISR prologues โก-mint8โ 8-bit int ๐ข-mdouble=bitsโ double width, in bits ๐-mlong-double=bitsโ long double width, in bits ๐-mn_flash=sizeโ flash size, set it ๐พ-mno-interruptsโ no interrupts ๐-mmain-is-OS_taskโ main is an OS task ๐ง-mrelaxโ relax ๐ง-mrmwโ read-modify-write ๐-mstrict-Xโ strict X register ๐ ง-mtiny-stackโ tiny stack ๐ค-mfract-convert-truncateโ fract convert truncate โ๏ธ-mshort-callsโ short calls โญ-nodevicelibโ no device library ๐ซ-nodevicespecsโ no device specs ๐ซ-Waddr-space-convertโ warn on address-space convert โ ๏ธ-Wmisspelled-isrโ warn on misspelled ISR โ ๏ธ
๐ Blackfin Options ๐
-mcpu=cpu[-sirevision]โ CPU, with optional SI revision ๐ข-msimโ simulator ๐ฎ-momit-leaf-frame-pointerโ omit leaf frame pointer ๐-mno-omit-leaf-frame-pointerโ keep leaf frame pointer ๐-mspecld-anomalyโ specld anomaly ๐ฉน-mno-specld-anomalyโ no specld anomaly ๐-mcsync-anomalyโ csync anomaly ๐ฉน-mno-csync-anomalyโ no csync anomaly ๐-mlow-64kโ low 64K ๐งฑ-mno-low64kโ no low 64K ๐-mstack-check-l1โ stack check L1 ๐-mid-shared-libraryโ ID shared library ๐-mno-id-shared-libraryโ no ID shared library ๐-mshared-library-id=nโ shared library ID, numbered ๐ข-mleaf-id-shared-libraryโ leaf ID shared library ๐-mno-leaf-id-shared-libraryโ no leaf ID shared library ๐-msep-dataโ separate data ๐๏ธ-mno-sep-dataโ no separate data ๐-mlong-callsโ long calls ๐-mno-long-callsโ no long calls ๐-mfast-fpโ fast FP ๐-minline-pltโ inline PLT ๐งต-mmulticoreโ multicore ๐งฉ-mcoreaโ core A ๐ ฐ๏ธ-mcorebโ core B ๐ ฑ๏ธ-msdramโ SDRAM ๐ง-micplbโ ICPLB ๐งท
๐ C6X Options ๐
-mbig-endianโ big endian ๐-mlittle-endianโ little endian ๐-march=cpuโ pick an arch ๐๏ธ-msimโ simulator ๐ฎ-msdata=sdata-typeโ small data type, pick one ๐๏ธ
๐ง CRIS Options ๐ง
-mcpu=cpuโ pick a CPU ๐-march=cpuโ pick an arch ๐๏ธ-mtune=cpuโ tune for a CPU ๐๏ธ-mmax-stack-frame=nโ max stack frame, numbered ๐-melinux-stacksize=nโ Linux stack size, numbered ๐-metrax4โ ETRAX 4 ๐ง-metrax100โ ETRAX 100 ๐ฏ-mpdebugโ debug ๐-mcc-initโ CC init ๐งน-mno-side-effectsโ no side effects ๐-mstack-alignโ stack align ๐-mdata-alignโ data align ๐-mconst-alignโ const align ๐-m32-bitโ 32-bit ๐ข-m16-bitโ 16-bit ๐ข-m8-bitโ 8-bit ๐ข-mno-prologue-epilogueโ no prologue or epilogue ๐-mno-gotpltโ no GOTPLT ๐-melfโ ELF ๐งฉ-maoutโ a.out ๐ฟ-melinuxโ Linux ๐ง-mlinuxโ Linux ๐ง-simโ simulator ๐ฎ-sim2โ simulator 2 ๐ฎ-mmul-bug-workaroundโ multiply bug workaround ๐ฉน-mno-mul-bug-workaroundโ no multiply bug workaround ๐
๐ CR16 Options ๐
-mmacโ MAC ๐-mcr16cplusโ CR16C+ ๐ง-mcr16cโ CR16C ๐งฉ-msimโ simulator ๐ฎ-mint32โ 32-bit int ๐ข-mbit-opsโ bit ops ๐งฎ-mdata-model=modelโ data model, pick one ๐๏ธ
๐ฟ C-SKY Options ๐ฟ
-march=archโ pick an arch ๐๏ธ-mcpu=cpuโ pick a CPU ๐-mbig-endianโ big endian ๐-EBโ big endian, the short way ๐-mlittle-endianโ little endian ๐-ELโ little endian, the short way ๐-mhard-floatโ hard float ๐ฅ-msoft-floatโ soft float ๐ง-mfpu=fpuโ pick an FPU ๐ง-mdouble-floatโ double float ๐ฆ-mfdivduโ FDIVDU โ-melrwโ ELRW ๐-mistackโ ISTACK ๐-mmpโ MP ๐งต-mcpโ CP ๐งฉ-mcacheโ cache ๐ง-msecurityโ security ๐-mtrustโ trust ๐ค-mdspโ DSP ๐ถ-medspโ EDSP ๐ถ-mvdspโ VDSP ๐ถ-mdivโ divide โ-msmartโ smart ๐ง-mhigh-registersโ high registers ๐-manchorโ anchor โ-mpushpopโ push and pop ๐ฅ-mmultiple-stldโ multiple load/store ๐ฆ-mconstpoolโ constant pool ๐-mstack-sizeโ stack size ๐-mccrtโ CCRT ๐งฉ-mbranch-cost=nโ branch cost, numbered ๐ฐ-mcse-ccโ CSE CC ๐งน-msched-prologโ scheduled prolog ๐
๐ Darwin Options ๐
-all_loadโ load everything ๐ฆ-allowable_clientโ allowable client ๐งโ๐คโ๐ง-archโ arch ๐๏ธ-arch_errors_fatalโ arch errors are fatal ๐-arch_onlyโ arch only ๐ฏ-bind_at_loadโ bind at load ๐-bundleโ bundle ๐งบ-bundle_loaderโ bundle loader ๐งบ-client_nameโ client name ๐ท๏ธ-compatibility_versionโ compatibility version ๐ข-current_versionโ current version ๐ข-dead_stripโ dead strip โ๏ธ-dependency-fileโ dependency file ๐-dylib_fileโ dylib file ๐-dylinker_install_nameโ dylinker install name ๐ท๏ธ-dynamicโ dynamic โก-dynamiclibโ dynamic lib ๐-exported_symbols_listโ exported symbols list ๐-filelistโ file list ๐-flat_namespaceโ flat namespace ๐บ๏ธ-force_cpusubtype_ALLโ force CPU subtype ALL ๐ช-force_flat_namespaceโ force flat namespace ๐บ๏ธ-headerpad_max_install_namesโ header pad for max install names ๐งท-iframeworkโ include framework ๐งฑ-image_baseโ image base ๐ผ๏ธ-initโ init ๐ฑ-install_nameโ install name ๐ท๏ธ-keep_private_externsโ keep private externs ๐-multi_moduleโ multi module ๐งฉ-multiply_definedโ multiply defined ๐-multiply_defined_unusedโ multiply defined, unused ๐-noall_loadโ no load-all ๐-no_dead_strip_inits_and_termsโ no dead strip for inits and terms ๐-nofixprebindingโ no fix prebinding ๐-nomultidefsโ no multidefs ๐-noprebindโ no prebind ๐-noseglinkeditโ no segment linkedit ๐-pagezero_sizeโ page zero size ๐-prebindโ prebind ๐-prebind_all_twolevel_modulesโ prebind all two-level modules ๐-private_bundleโ private bundle ๐-read_only_relocsโ read-only relocs ๐-sectalignโ section align ๐-sectobjectsymbolsโ section object symbols ๐งพ-whyloadโ why load โ-seg1addrโ seg1 address ๐-sectcreateโ section create ๐ ๏ธ-sectobjectsymbolsโ section object symbols ๐งพ-sectorderโ section order ๐-segaddrโ segment address ๐-segs_read_only_addrโ read-only segment address ๐-segs_read_write_addrโ read-write segment address ๐-seg_addr_tableโ segment address table ๐๏ธ-seg_addr_table_filenameโ segment address table filename ๐-seglinkeditโ segment linkedit ๐-segprotโ segment protection ๐ก๏ธ-segs_read_only_addrโ read-only segment address ๐-segs_read_write_addrโ read-write segment address ๐-single_moduleโ single module ๐งฑ-staticโ static ๐ง-sub_libraryโ sub library ๐-sub_umbrellaโ sub umbrella โ๏ธ-twolevel_namespaceโ two-level namespace ๐บ๏ธ-umbrellaโ umbrella โ๏ธ-undefinedโ undefined โ-unexported_symbols_listโ unexported symbols list ๐-weak_reference_mismatchesโ weak reference mismatches โ ๏ธ-whatsloadedโ what's loaded ๐-Fโ framework path ๐-gusedโ debug, only used ๐-gfullโ full debug ๐-mmacosx-version-min=versionโ minimum macOS version ๐-mkernelโ kernel ๐ง-mone-byte-boolโ one-byte bool ๐ข
๐งก DEC Alpha Options ๐งก
-mno-fp-regsโ no FP regs ๐-msoft-floatโ soft float ๐ง-mieeeโ IEEE ๐งฎ-mieee-with-inexactโ IEEE with inexact ๐งฎ-mieee-conformantโ IEEE conformant โ-mfp-trap-mode=modeโ FP trap mode, pick one ๐ชค-mfp-rounding-mode=modeโ FP rounding mode, pick one ๐-mtrap-precision=modeโ trap precision, pick one ๐ฏ-mbuild-constantsโ build constants ๐งฑ-mcpu=cpu-typeโ pick a CPU type ๐-mtune=cpu-typeโ tune for a CPU type ๐๏ธ-mbwxโ BWX ๐ข-mmaxโ MAX ๐-mfixโ FIX ๐ฉน-mcixโ CIX ๐ข-mfloat-vaxโ VAX float ๐ฆ-mfloat-ieeeโ IEEE float ๐งฎ-mexplicit-relocsโ explicit relocs ๐งฉ-msmall-dataโ small data ๐๏ธ-mlarge-dataโ large data ๐๏ธ-msmall-textโ small text ๐-mlarge-textโ large text ๐-mmemory-latency=timeโ memory latency, set the time โฑ๏ธ
๐ eBPF Options ๐
-mbig-endianโ big endian ๐-mlittle-endianโ little endian ๐-mkernel=versionโ kernel version ๐ง-mframe-limit=bytesโ frame limit, in bytes ๐-mxbpfโ XBPF ๐งฉ
๐ FR30 Options ๐
-msmall-modelโ small model ๐ค-mno-lsimโ no LSIM ๐
๐ช FT32 Options ๐ช
-msimโ simulator ๐ฎ-mlraโ LRA ๐ง-mnodivโ no divide ๐-mft32bโ FT32B ๐งฉ-mcompressโ compress ๐๏ธ-mnopmโ no PM ๐
๐ฆ FRV Options ๐ฆ
-mgpr-32โ 32 GPRs ๐ข-mgpr-64โ 64 GPRs ๐ข-mfpr-32โ 32 FPRs ๐ข-mfpr-64โ 64 FPRs ๐ข-mhard-floatโ hard float ๐ฅ-msoft-floatโ soft float ๐ง-malloc-ccโ allocate CC ๐ง-mfixed-ccโ fixed CC ๐-mdwordโ doubleword ๐ข-mno-dwordโ no doubleword ๐-mdoubleโ double ๐ฆ-mno-doubleโ no double ๐-mmediaโ media ๐ถ-mno-mediaโ no media ๐-mmuladdโ multiply-add โ-mno-muladdโ no multiply-add ๐-mfdpicโ FDPIC ๐งฉ-minline-pltโ inline PLT ๐งต-mgprel-roโ GP-relative read-only ๐-multilib-library-picโ multilib library PIC ๐-mlinked-fpโ linked FP ๐-mlong-callsโ long calls ๐-malign-labelsโ align labels ๐ฏ-mlibrary-picโ library PIC ๐-macc-4โ 4 accumulators ๐ข-macc-8โ 8 accumulators ๐ข-mpackโ pack ๐ฆ-mno-packโ no pack ๐-mno-eflagsโ no eflags ๐-mcond-moveโ conditional move ๐-mno-cond-moveโ no conditional move ๐-moptimize-membarโ optimise membar ๐งน-mno-optimize-membarโ no membar optimisation ๐-msccโ SCC ๐ง-mno-sccโ no SCC ๐-mcond-execโ conditional execution ๐-mno-cond-execโ no conditional execution ๐-mvliw-branchโ VLIW branch ๐งฉ-mno-vliw-branchโ no VLIW branch ๐-mmulti-cond-execโ multi conditional execution ๐-mno-multi-cond-execโ no multi conditional execution ๐-mnested-cond-execโ nested conditional execution ๐ช-mno-nested-cond-execโ no nested conditional execution ๐-mtomcat-statsโ Tomcat stats ๐-mTLSโ TLS ๐งต-mtlsโ TLS ๐งต-mcpu=cpuโ pick a CPU ๐
๐ง GNU/Linux Options ๐ง
-mglibcโ glibc ๐-muclibcโ uClibc ๐-mmuslโ musl ๐-mbionicโ Bionic ๐ค-mandroidโ Android ๐ค-tno-android-ccโ no Android CC ๐-tno-android-ldโ no Android LD ๐
๐บ H8/300 Options ๐บ
-mrelaxโ relax ๐ง-mhโ H ๐ ท-msโ S ๐ ข-mnโ N ๐ -mexrโ EXR ๐งฉ-mno-exrโ no EXR ๐-mint32โ 32-bit int ๐ข-malign-300โ align 300 ๐
๐ฐ HPPA Options ๐ฐ
-march=architecture-typeโ pick an architecture type ๐๏ธ-mcaller-copiesโ caller copies ๐-mdisable-fpregsโ disable FP regs ๐ซ-mdisable-indexingโ disable indexing ๐ซ-mfast-indirect-callsโ fast indirect calls ๐-mgasโ GAS ๐งต-mgnu-ldโ GNU LD ๐-mhp-ldโ HP LD ๐ข-mfixed-range=register-rangeโ fixed register range ๐-mjump-in-delayโ jump in delay slot ๐ฆ-mlinker-optโ linker optimisation ๐งน-mlong-callsโ long calls ๐-mlong-load-storeโ long load and store ๐ฆ-mno-disable-fpregsโ don't disable FP regs ๐-mno-disable-indexingโ don't disable indexing ๐-mno-fast-indirect-callsโ no fast indirect calls ๐-mno-gasโ no GAS ๐-mno-jump-in-delayโ no jump in delay slot ๐-mno-long-load-storeโ no long load and store ๐-mno-portable-runtimeโ no portable runtime ๐-mno-soft-floatโ no soft float ๐-mno-space-regsโ no space regs ๐-msoft-floatโ soft float ๐ง-mpa-risc-1-0โ PA-RISC 1.0 ๐ง-mpa-risc-1-1โ PA-RISC 1.1 ๐ง-mpa-risc-2-0โ PA-RISC 2.0 ๐ง-mportable-runtimeโ portable runtime ๐งณ-mschedule=cpu-typeโ schedule for a CPU type ๐๏ธ-mspace-regsโ space regs ๐-msioโ SIO ๐-mwsioโ WSIO ๐-munix=unix-stdโ UNIX standard ๐ง-nolibdldโ no libdld ๐ซ-staticโ static ๐ง-threadsโ threads ๐งต
๐๏ธ IA-64 Options ๐๏ธ
-mbig-endianโ big endian ๐-mlittle-endianโ little endian ๐-mgnu-asโ GNU as ๐งต-mgnu-ldโ GNU LD ๐-mno-picโ no PIC ๐-mvolatile-asm-stopโ volatile asm stop ๐-mregister-namesโ register names ๐ท๏ธ-msdataโ small data ๐๏ธ-mno-sdataโ no small data ๐-mconstant-gpโ constant GP ๐-mauto-picโ auto PIC ๐ค-mfused-maddโ fused multiply-add โ-minline-float-divide-min-latencyโ inline float divide, min latency โฑ๏ธ-minline-float-divide-max-throughputโ inline float divide, max throughput ๐-mno-inline-float-divideโ no inline float divide ๐-minline-int-divide-min-latencyโ inline int divide, min latency โฑ๏ธ-minline-int-divide-max-throughputโ inline int divide, max throughput ๐-mno-inline-int-divideโ no inline int divide ๐-minline-sqrt-min-latencyโ inline sqrt, min latency โฑ๏ธ-minline-sqrt-max-throughputโ inline sqrt, max throughput ๐-mno-inline-sqrtโ no inline sqrt ๐-mdwarf2-asmโ DWARF2 asm ๐-mearly-stop-bitsโ early stop bits โน๏ธ-mfixed-range=register-rangeโ fixed register range ๐-mtls-size=tls-sizeโ TLS size ๐-mtune=cpu-typeโ tune for a CPU type ๐๏ธ-milp32โ ILP32 ๐ข-mlp64โ LP64 ๐ข-msched-br-data-specโ scheduling branch data speculation ๐๏ธ-msched-ar-data-specโ scheduling AR data speculation ๐๏ธ-msched-control-specโ scheduling control speculation ๐๏ธ-msched-br-in-data-specโ scheduling branch in data speculation ๐๏ธ-msched-ar-in-data-specโ scheduling AR in data speculation ๐๏ธ-msched-in-control-specโ scheduling in control speculation ๐๏ธ-msched-spec-ldcโ scheduling spec LDC ๐๏ธ-msched-spec-control-ldcโ scheduling spec control LDC ๐๏ธ-msched-prefer-non-data-spec-insnsโ prefer non-data-spec insns ๐๏ธ-msched-prefer-non-control-spec-insnsโ prefer non-control-spec insns ๐๏ธ-msched-stop-bits-after-every-cycleโ stop bits after every cycle โน๏ธ-msched-count-spec-in-critical-pathโ count spec in critical path ๐งฎ-msel-sched-dont-check-control-specโ selective scheduling, skip control spec checks ๐๏ธ-msched-fp-mem-deps-zero-costโ FP memory deps at zero cost ๐ธ-msched-max-memory-insns-hard-limitโ max memory insns, hard limit ๐-msched-max-memory-insns=max-insnsโ max memory insns, set the max ๐ข
๐ LM32 Options ๐
-mbarrel-shift-enabledโ barrel shift enabled ๐-mdivide-enabledโ divide enabled โ-mmultiply-enabledโ multiply enabled โ๏ธ-msign-extend-enabledโ sign extend enabled ๐ข-muser-enabledโ user enabled ๐ค
๐ท M32R/D Options ๐ท
-m32r2โ M32R2 ๐งฉ-m32rxโ M32RX ๐งฉ-m32rโ M32R ๐งฉ-mdebugโ debug ๐-malign-loopsโ align loops ๐ฏ-mno-align-loopsโ no loop alignment ๐-missue-rate=numberโ issue rate, numbered ๐ข-mbranch-cost=numberโ branch cost, numbered ๐ฐ-mmodel=code-size-model-typeโ code size model type ๐-msdata=sdata-typeโ small data type ๐๏ธ-mno-flush-funcโ no flush function ๐-mflush-func=nameโ flush function, pick a name ๐งน-mno-flush-trapโ no flush trap ๐-mflush-trap=numberโ flush trap, numbered ๐ชค-G numโ small data threshold, numbered ๐ข
๐ป M32C Options ๐ป
-mcpu=cpuโ pick a CPU ๐-msimโ simulator ๐ฎ-memregs=numberโ emregs, numbered ๐ข
๐ฆ M680x0 Options ๐ฆ
-march=archโ pick an arch ๐๏ธ-mcpu=cpuโ pick a CPU ๐-mtune=tuneโ tune for a target ๐๏ธ-m68000โ 68000 ๐ฆ-m68020โ 68020 ๐ฆ-m68020-40โ 68020-40 ๐ฆ-m68020-60โ 68020-60 ๐ฆ-m68030โ 68030 ๐ฆ-m68040โ 68040 ๐ฆ-m68060โ 68060 ๐ฆ-mcpu32โ CPU32 ๐งฉ-m5200โ 5200 ๐งฉ-m5206eโ 5206e ๐งฉ-m528xโ 528x ๐งฉ-m5307โ 5307 ๐งฉ-m5407โ 5407 ๐งฉ-mcfv4eโ ColdFire V4e ๐งฉ-mbitfieldโ bitfield ๐งฎ-mno-bitfieldโ no bitfield ๐-mc68000โ C68000 ๐ฆ-mc68020โ C68020 ๐ฆ-mnobitfieldโ no bitfield ๐-mrtdโ RTD ๐-mno-rtdโ no RTD ๐-mdivโ divide โ-mno-divโ no divide ๐-mshortโ short ๐ข-mno-shortโ no short ๐-mhard-floatโ hard float ๐ฅ-m68881โ 68881 ๐ง-msoft-floatโ soft float ๐ง-mpcrelโ PC-relative ๐งญ-malign-intโ align int ๐ฏ-mstrict-alignโ strict align ๐-msep-dataโ separate data ๐๏ธ-mno-sep-dataโ no separate data ๐-mshared-library-id=nโ shared library ID, numbered ๐ข-mid-shared-libraryโ ID shared library ๐-mno-id-shared-libraryโ no ID shared library ๐-mxgotโ XGOT ๐งฉ-mno-xgotโ no XGOT ๐-mlong-jump-table-offsetsโ long jump table offsets ๐ช
๐ฅ MCore Options ๐ฅ
-mhardlitโ hard literals ๐งฑ-mno-hardlitโ no hard literals ๐-mdivโ divide โ-mno-divโ no divide ๐-mrelax-immediatesโ relax immediates ๐ง-mno-relax-immediatesโ no relaxed immediates ๐-mwide-bitfieldsโ wide bitfields ๐งฎ-mno-wide-bitfieldsโ no wide bitfields ๐-m4byte-functionsโ 4-byte functions ๐ข-mno-4byte-functionsโ no 4-byte functions ๐-mcallgraph-dataโ callgraph data ๐บ๏ธ-mno-callgraph-dataโ no callgraph data ๐-mslow-bytesโ slow bytes ๐ข-mno-slow-bytesโ no slow bytes ๐-mno-lsimโ no LSIM ๐-mlittle-endianโ little endian ๐-mbig-endianโ big endian ๐-m210โ 210 ๐งฉ-m340โ 340 ๐งฉ-mstack-incrementโ stack increment ๐
๐ MeP Options ๐
-mabsdiffโ absolute difference ๐งฎ-mall-optsโ all the opts ๐-maverageโ average ๐-mbased=nโ based, numbered ๐ข-mbitopsโ bit ops ๐งฎ-mc=nโ C, numbered ๐ข-mclipโ clip โ๏ธ-mconfig=nameโ config, pick a name โ๏ธ-mcopโ coprocessor ๐งฉ-mcop32โ 32-bit coprocessor ๐งฉ-mcop64โ 64-bit coprocessor ๐งฉ-mivc2โ IVC2 ๐งฉ-mdcโ DC ๐งฉ-mdivโ divide โ-mebโ big endian ๐-melโ little endian ๐-mio-volatileโ volatile I/O ๐-mlโ L ๐ ป-mleadzโ leading zeros 0๏ธโฃ-mmโ M ๐ ผ-mminmaxโ min and max ๐-mmultโ multiply โ๏ธ-mno-optsโ no opts ๐-mrepeatโ repeat ๐-msโ S ๐ ข-msaturโ saturate ๐ฅ-msdramโ SDRAM ๐ง-msimโ simulator ๐ฎ-msimnovecโ simulator, no vector ๐ฎ-mtfโ TF ๐งฉ-mtiny=nโ tiny, numbered ๐ข
๐ฃ MicroBlaze Options ๐ฃ
-msoft-floatโ soft float ๐ง-mhard-floatโ hard float ๐ฅ-msmall-dividesโ small divides โ-mcpu=cpuโ pick a CPU ๐-mmemcpyโ memcpy ๐-mxl-soft-mulโ XL soft multiply โ๏ธ-mxl-soft-divโ XL soft divide โ-mxl-barrel-shiftโ XL barrel shift ๐-mxl-pattern-compareโ XL pattern compare ๐-mxl-stack-checkโ XL stack check ๐-mxl-gp-optโ XL GP opt ๐งน-mno-clearbssโ no clear BSS ๐-mxl-multiply-highโ XL multiply high โ๏ธ-mxl-float-convertโ XL float convert ๐-mxl-float-sqrtโ XL float sqrt ๐งฎ-mbig-endianโ big endian ๐-mlittle-endianโ little endian ๐-mxl-reorderโ XL reorder ๐-mxl-mode-app-modelโ XL mode app model ๐งฉ-mpic-data-is-text-relativeโ PIC data is text-relative ๐งญ
OKAY bestie, the MIPS list is LONG and I'm not even sorry ๐ญ Here are the machine-specific flags, grouped by target, with the page's list kept exactly as written ๐
๐ฆ MIPS Options ๐ฆ
-EL-EB-march=arch-mtune=arch-mips1-mips2-mips3-mips4-mips32-mips32r2-mips32r3-mips32r5-mips32r6-mips64-mips64r2-mips64r3-mips64r5-mips64r6-mips16-mno-mips16-mflip-mips16-minterlink-compressed-mno-interlink-compressed-minterlink-mips16-mno-interlink-mips16-mabi=abi-mabicalls-mno-abicalls-mshared-mno-shared-mplt-mno-plt-mxgot-mno-xgot-mgp32-mgp64-mfp32-mfpxx-mfp64-mhard-float-msoft-float-mno-float-msingle-float-mdouble-float-modd-spreg-mno-odd-spreg-mabs=mode-mnan=encoding-mdsp-mno-dsp-mdspr2-mno-dspr2-mmcu-mmno-mcu-meva-mno-eva-mvirt-mno-virt-mxpa-mno-xpa-mcrc-mno-crc-mginv-mno-ginv-mmicromips-mno-micromips-mmsa-mno-msa-mloongson-mmi-mno-loongson-mmi-mloongson-ext-mno-loongson-ext-mloongson-ext2-mno-loongson-ext2-mfpu=fpu-type-msmartmips-mno-smartmips-mpaired-single-mno-paired-single-mdmx-mno-mdmx-mips3d-mno-mips3d-mmt-mno-mt-mllsc-mno-llsc-mlong64-mlong32-msym32-mno-sym32-Gnum-mlocal-sdata-mno-local-sdata-mextern-sdata-mno-extern-sdata-mgpopt-mno-gopt-membedded-data-mno-embedded-data-muninit-const-in-rodata-mno-uninit-const-in-rodata-mcode-readable=setting-msplit-addresses-mno-split-addresses-mexplicit-relocs-mno-explicit-relocs-mcheck-zero-division-mno-check-zero-division-mdivide-traps-mdivide-breaks-mload-store-pairs-mno-load-store-pairs-mmemcpy-mno-memcpy-mlong-calls-mno-long-calls-mmad-mno-mad-mimadd-mno-imadd-mfused-madd-mno-fused-madd-nocpp-mfix-24k-mno-fix-24k-mfix-r4000-mno-fix-r4000-mfix-r4400-mno-fix-r4400-mfix-r5900-mno-fix-r5900-mfix-r10000-mno-fix-r10000-mfix-rm7000-mno-fix-rm7000-mfix-vr4120-mno-fix-vr4120-mfix-vr4130-mno-fix-vr4130-mfix-sb1-mno-fix-sb1-mflush-func=func-mno-flush-func-mbranch-cost=num-mbranch-likely-mno-branch-likely-mcompact-branches=policy-mfp-exceptions-mno-fp-exceptions-mvr4130-align-mno-vr4130-align-msynci-mno-synci-mlxc1-sxc1-mno-lxc1-sxc1-mmadd4-mno-madd4-mrelax-pic-calls-mno-relax-pic-calls-mmcount-ra-address-mframe-header-opt-mno-frame-header-opt
๐ง MMIX Options ๐ง
-mlibfuncs-mno-libfuncs-mepsilon-mno-epsilon-mabi=gnu-mabi=mmixware-mzero-extend-mknuthdiv-mtoplevel-symbols-melf-mbranch-predict-mno-branch-predict-mbase-addresses-mno-base-addresses-msingle-exit-mno-single-exit
๐ MN10300 Options ๐
-mmult-bug-mno-mult-bug-mno-am33-mam33-mam33-2-mam34-mtune=cpu-type-mreturn-pointer-on-d0-mno-crt0-mrelax-mliw-msetlb
๐ธ Moxie Options ๐ธ
-meb-mel-mmul.x-mno-crt0
โจ MSP430 Options โจ
-msim-masm-hex-mmcu=-mcpu=-mlarge-msmall-mrelax-mwarn-mcu-mcode-region=-mdata-region=-msilicon-errata=-msilicon-errata-warn=-mhwmult=-minrt-mtiny-printf
๐ NDS32 Options ๐
-mbig-endian-mlittle-endian-mreduced-regs-mfull-regs-mcmov-mno-cmov-mext-perf-mno-ext-perf-mext-perf2-mno-ext-perf2-mext-string-mno-ext-string-mv3push-mno-v3push-m16bit-mno-16bit-misr-vector-size=num-mcache-block-size=num-march=arch-mcmodel=code-model-mctor-dtor-mrelax
๐ Nios II Options ๐
-G num-mgpopt=option-mgpopt-mno-gpopt-mgprel-sec=regexp-mr0rel-sec=regexp-mel-meb-mno-bypass-cache-mbypass-cache-mno-cache-volatile-mcache-volatile-mno-fast-sw-div-mfast-sw-div-mhw-mul-mno-hw-mul-mhw-mulx-mno-hw-mulx-mno-hw-div-mhw-div-mcustom-insn=N-mno-custom-insn-mcustom-fpu-cfg=name-mhal-msmallc-msys-crt0=name-msys-lib=name-march=arch-mbmx-mno-bmx-mcdx-mno-cdx
๐ Nvidia PTX Options ๐
-m32-m64-mmainkernel-moptimize
๐ซถ OpenRISC Options ๐ซถ
-mboard=name-mnewlib-mhard-mul-mhard-div-msoft-mul-msoft-div-msoft-float-mhard-float-mdouble-float-munordered-float-mcmov-mror-mrori-msext-msfimm-mshftimm
๐ฅ PDP-11 Options ๐ฅ
-mfpu-msoft-float-mac0-mno-ac0-m40-m45-m10-mint32-mno-int16-mint16-mno-int32-msplit-munix-asm-mdec-asm-mgnu-asm-mlra
๐ง picoChip Options ๐ง
-mae=ae_type-mvliw-lookahead=N-msymbol-as-address-mno-inefficient-warnings
๐ฆ PowerPC Options ๐ฆ
This one's a little cross-reference moment, bestie. See RS/6000 and PowerPC Options. ๐ง
๐ธ PRU Options ๐ธ
-mmcu=mcu-minrt-mno-relax-mloop-mabi=variant
๐ RISC-V Options ๐
-mbranch-cost=N-instruction-mplt-mno-plt-mabi=ABI-string-mfdiv-mno-fdiv-mdiv-mno-div-march=ISA-string-mtune=processor-string-mpreferred-stack-boundary=num-msmall-data-limit=N-bytes-msave-restore-mno-save-restore-mstrict-align-mno-strict-align-mcmodel=medlow-mcmodel=medany-mexplicit-relocs-mno-explicit-relocs-mrelax-mno-relax-mriscv-attribute-mmo-riscv-attribute-malign-data=type
๐ RL78 Options ๐
-msim-mmul=none-mmul=g13-mmul=g14-mallregs-mcpu=g10-mcpu=g13-mcpu=g14-mg10-mg13-mg14-m64bit-doubles-m32bit-doubles-msave-mduc-in-interrupts
๐ RS/6000 and PowerPC Options ๐
-mcpu=cpu-type-mtune=cpu-type-mcmodel=code-model-mpowerpc64-maltivec-mno-altivec-mpowerpc-gpopt-mno-powerpc-gpopt-mpowerpc-gfxopt-mno-powerpc-gfxopt-mmfcrf-mno-mfcrf-mpopcntb-mno-popcntb-mpopcntd-mno-popcntd-mfprnd-mno-fprnd-mcmpb-mno-cmpb-mhard-dfp-mno-hard-dfp-mfull-toc-mminimal-toc-mno-fp-in-toc-mno-sum-in-toc-m64-m32-mxl-compat-mno-xl-compat-mpe-malign-power-malign-natural-msoft-float-mhard-float-mmultiple-mno-multiple-mupdate-mno-update-mavoid-indexed-addresses-mno-avoid-indexed-addresses-mfused-madd-mno-fused-madd-mbit-align-mno-bit-align-mstrict-align-mno-strict-align-mrelocatable-mno-relocatable-mrelocatable-lib-mno-relocatable-lib-mtoc-mno-toc-mlittle-mlittle-endian-mbig-mbig-endian-mdynamic-no-pic-mswdiv-msingle-pic-base-mprioritize-restricted-insns=priority-msched-costly-dep=dependence_type-minsert-sched-nops=scheme-mcall-aixdesc-mcall-eabi-mcall-freebsd-mcall-linux-mcall-netbsd-mcall-openbsd-mcall-sysv-mcall-sysv-eabi-mcall-sysv-noeabi-mtraceback=traceback_type-maix-struct-return-msvr4-struct-return-mabi=abi-type-msecure-plt-mbss-plt-mlongcall-mno-longcall-mpltseq-mno-pltseq-mblock-move-inline-limit=num-mblock-compare-inline-limit=num-mblock-compare-inline-loop-limit=num-mstring-compare-inline-limit=num-misel-mno-isel-mvrsave-mno-vrsave-mmulhw-mno-mulhw-mdlmzb-mno-dlmzb-mprototype-mno-prototype-msim-mmvme-mads-myellowknife-memb-msdata-msdata=opt-mreadonly-in-sdata-mvxworks-G num-mrecip-mrecip=opt-mno-recip-mrecip-precision-mno-recip-precision-mveclibabi=type-mfriz-mno-friz-mpointers-to-nested-functions-mno-pointers-to-nested-functions-msave-toc-indirect-mno-save-toc-indirect-mpower8-fusion-mno-mpower8-fusion-mpower8-vector-mno-power8-vector-mcrypto-mno-crypto-mhtm-mno-htm-mquad-memory-mno-quad-memory-mquad-memory-atomic-mno-quad-memory-atomic-mcompat-align-parm-mno-compat-align-parm-mfloat128-mno-float128-mfloat128-hardware-mno-float128-hardware-mgnu-attribute-mno-gnu-attribute-mstack-protector-guard=guard-mstack-protector-guard-reg=reg-mstack-protector-guard-offset=offset-mprefixed-mno-prefixed-mpcrel-mno-pcrel-mmma-mno-mmma
๐ฆ RX Options ๐ฆ
-m64bit-doubles-m32bit-doubles-fpu-nofpu-mcpu=-mbig-endian-data-mlittle-endian-data-msmall-data-msim-mno-sim-mas100-syntax-mno-as100-syntax-mrelax-mmax-constant-size=-mint-register=-mpid-mallow-string-insns-mno-allow-string-insns-mjsr-mno-warn-multiple-fast-interrupts-msave-acc-in-interrupts
๐ธ S/390 and zSeries Options ๐ธ
-mtune=cpu-type-march=cpu-type-mhard-float-msoft-float-mhard-dfp-mno-hard-dfp-mlong-double-64-mlong-double-128-mbackchain-mno-backchain-mpacked-stack-mno-packed-stack-msmall-exec-mno-small-exec-mmvcle-mno-mvcle-m64-m31-mdebug-mno-debug-mesa-mzarch-mhtm-mvx-mzvector-mtpf-trace-mno-tpf-trace-mtpf-trace-skip-mno-tpf-trace-skip-mfused-madd-mno-fused-madd-mwarn-framesize-mwarn-dynamicstack-mstack-size-mstack-guard-mhotpatch=halfwords,halfwords
๐ง Score Options ๐ง
-meb-mel-mnhwloop-muls-mmac-mscore5-mscore5u-mscore7-mscore7d
๐ SH Options ๐
-m1-m2-m2e-m2a-nofpu-m2a-single-only-m2a-single-m2a-m3-m3e-m4-nofpu-m4-single-only-m4-single-m4-m4a-nofpu-m4a-single-only-m4a-single-m4a-m4al-mb-ml-mdalign-mrelax-mbigtable-mfmovd-mrenesas-mno-renesas-mnomacsave-mieee-mno-ieee-mbitops-misize-minline-ic_invalidate-mpadstruct-mprefergot-musermode-multcost=number-mdiv=strategy-mdivsi3_libfunc=name-mfixed-range=register-range-maccumulate-outgoing-args-matomic-model=atomic-model-mbranch-cost=num-mzdcbranch-mno-zdcbranch-mcbranch-force-delay-slot-mfused-madd-mno-fused-madd-mfsca-mno-fsca-mfsrra-mno-fsrra-mpretend-cmove-mtas
๐ซถ Solaris 2 Options ๐ซถ
-mclear-hwcap-mno-clear-hwcap-mimpure-text-mno-impure-text-pthreads
๐ฅ SPARC Options ๐ฅ
-mcpu=cpu-type-mtune=cpu-type-mcmodel=code-model-mmemory-model=mem-model-m32-m64-mapp-regs-mno-app-regs-mfaster-structs-mno-faster-structs-mflat-mno-flat-mfpu-mno-fpu-mhard-float-msoft-float-mhard-quad-float-msoft-quad-float-mstack-bias-mno-stack-bias-mstd-struct-return-mno-std-struct-return-munaligned-doubles-mno-unaligned-doubles-muser-mode-mno-user-mode-mv8plus-mno-v8plus-mvis-mno-vis-mvis2-mno-vis2-mvis3-mno-vis3-mvis4-mno-vis4-mvis4b-mno-vis4b-mcbcond-mno-cbcond-mfmaf-mno-fmaf-mfsmuld-mno-fsmuld-mpopc-mno-popc-msubxc-mno-subxc-mfix-at697f-mfix-ut699-mfix-ut700-mfix-gr712rc-mlra-mno-lra
๐ง System V Options ๐ง
-Qy-Qn-YP,paths-Ym,dir
๐ TILE-Gx Options ๐
-mcpu=CPU-m32-m64-mbig-endian-mlittle-endian-mcmodel=code-model
๐ TILEPro Options ๐
-mcpu=cpu-m32
๐ V850 Options ๐
-mlong-calls-mno-long-calls-mep-mno-ep-mprolog-function-mno-prolog-function-mspace-mtda=n-msda=n-mzda=n-mapp-regs-mno-app-regs-mdisable-callt-mno-disable-callt-mv850e2v3-mv850e2-mv850e1-mv850es-mv850e-mv850-mv850e3v5-mloop-mrelax-mlong-jumps-msoft-float-mhard-float-mgcc-abi-mrh850-abi-mbig-switch
๐ฆ VAX Options ๐ฆ
-mg-mgnu-munix
๐ Visium Options
okay bestie, these are the Visium flags ๐ฆ
-mdebug -msim -mfpu -mno-fpu -mhard-float
-msoft-float -mcpu=cpu-type -mtune=cpu-type -msv-mode -muser-mode
๐ธ VMS Options
the VMS crew has their own set โจ
-mvms-return-codes -mdebug-main=prefix -mmalloc64
-mpointer-size=size
๐ง VxWorks Options
VxWorks gets its own little squad ๐ซถ
-mrtp -non-static -Bstatic -Bdynamic -Xbind-lazy
-Xbind-now
๐ x86 Options
the x86 list is literally massive, no cap ๐ every single one is here, don't worry
-mtune=cpu-type -march=cpu-type -mtune-ctrl=feature-list
-mdump-tune-features -mno-default -mfpmath=unit -masm=dialect
-mno-fancy-math-387 -mno-fp-ret-in-387 -m80387 -mhard-float
-msoft-float -mno-wide-multiply -mrtd -malign-double
-mpreferred-stack-boundary=num -mincoming-stack-boundary=num -mcld
-mcx16 -msahf -mmovbe -mcrc32 -mrecip -mrecip=opt -mvzeroupper
-mprefer-avx128 -mprefer-vector-width=opt -mmmx -msse -msse2
-msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx -mavx2 -mavx512f
-mavx512pf -mavx512er -mavx512cd -mavx512vl -mavx512bw
-mavx512dq -mavx512ifma -mavx512vbmi -msha -maes -mpclmul
-mfsgsbase -mrdrnd -mf16c -mfma -mpconfig -mwbnoinvd -mptwrite
-mprefetchwt1 -mclflushopt -mclwb -mxsavec -mxsaves -msse4a
-m3dnow -m3dnowa -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop
-madx -mlzcnt -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mhle
-mlwp -mmwaitx -mclzero -mpku -mthreads -mgfni -mvaes
-mwaitpkg -mshstk -mmanual-endbr -mforce-indirect-call
-mavx512vbmi2 -mavx512bf16 -menqcmd -mvpclmulqdq -mavx512bitalg
-mmovdiri -mmovdir64b -mavx512vpopcntdq -mavx5124fmaps
-mavx512vnni -mavx5124vnniw -mprfchw -mrdpid -mrdseed -msgx
-mavx512vp2intersect -mcldemote -mms-bitfields
-mno-align-stringops -minline-all-stringops
-minline-stringops-dynamically -mstringop-strategy=alg
-mmemcpy-strategy=strategy -mmemset-strategy=strategy -mpush-args
-maccumulate-outgoing-args -m128bit-long-double -m96bit-long-double
-mlong-double-64 -mlong-double-80 -mlong-double-128 -mregparm=num
-msseregparm -mveclibabi=type -mvect8-ret-in-mem -mpc32 -mpc64
-mpc80 -mstackrealign -momit-leaf-frame-pointer -mno-red-zone
-mno-tls-direct-seg-refs -mcmodel=code-model -mabi=name
-maddress-mode=mode -m32 -m64 -mx32 -m16 -miamcu
-mlarge-data-threshold=num -msse2avx -mfentry -mrecord-mcount
-mnop-mcount -m8bit-idiv -minstrument-return=type
-mfentry-name=name -mfentry-section=name
-mavx256-split-unaligned-load -mavx256-split-unaligned-store
-malign-data=type -mstack-protector-guard=guard
-mstack-protector-guard-reg=reg
-mstack-protector-guard-offset=offset
-mstack-protector-guard-symbol=symbol -mgeneral-regs-only
-mcall-ms2sysv-xlogues -mindirect-branch=choice
-mfunction-return=choice -mindirect-branch-register
-mharden-sls=choice -mindirect-branch-cs-prefix
๐ช x86 Windows Options
the Windows corner of the x86 family ๐
-mconsole -mcygwin -mno-cygwin -mdll
-mnop-fun-dllimport -mthread -municode -mwin32 -mwindows
-fno-set-stack-executable
๐ฆ Xstormy16 Options
just one little flag for the Xstormy16 folks ๐
-msim
๐ Xtensa Options
the Xtensa list is giving main character energy ๐
-mconst16 -mno-const16 -mfused-madd -mno-fused-madd
-mforce-no-pic -mserialize-volatile -mno-serialize-volatile
-mtext-section-literals -mno-text-section-literals -mauto-litpools
-mno-auto-litpools -mtarget-align -mno-target-align -mlongcalls
-mno-longcalls
โญ zSeries Options
for zSeries, you just gotta go look at S/390 and zSeries Options instead ๐
โจ Options Controlling the Kind of Output โจ
okay so compiling can have up to four stages: preprocessing, compilation proper, assembly, and linking, always in that order ๐ฅ GCC can preprocess and compile a bunch of files into either several assembler input files or one assembler input file. then each assembler input file becomes an object file, and linking mashes all the object files together (the newly compiled ones and the ones you gave it) into an executable file. it's giving teamwork ๐ซถ
for any given input file, the file name suffix decides what kind of compilation happens ๐ฆ
file.cโ C source code that has to be preprocessed first ๐file.iโ C source code that should NOT be preprocessed ๐ธfile.iiโ C++ source code that should NOT be preprocessed ๐ธfile.mโ Objective-C source code. heads up, you have to link with the libobjc library or your Objective-C program won't work ๐file.miโ Objective-C source code that should NOT be preprocessed ๐ธfile.mm,file.Mโ Objective-C++ source code. same deal, you must link with libobjc for it to work. and yes,.Mmeans a literal capital M ๐ฅfile.miiโ Objective-C++ source code that should NOT be preprocessed ๐ธfile.hโ a C, C++, Objective-C, or Objective-C++ header file that gets turned into a precompiled header (that's the default). or, if you use-fdump-ada-spec, a C or C++ header file gets turned into an Ada spec โจfile.cc,file.cp,file.cxx,file.cpp,file.CPP,file.c++,file.Cโ C++ source code that has to be preprocessed. quick note: in.cxx, the last two letters have to be literallyx, and.Cmeans a literal capital C ๐งfile.mm,file.Mโ Objective-C++ source code that has to be preprocessed ๐file.miiโ Objective-C++ source code that should NOT be preprocessed (yes, it's listed twice, the vibes are consistent ๐ญ)file.hh,file.H,file.hp,file.hxx,file.hpp,file.HPP,file.h++,file.tccโ C++ header files that get turned into a precompiled header or an Ada spec ๐file.f,file.for,file.ftnโ fixed form Fortran source code that should NOT be preprocessed ๐file.F,file.FOR,file.fpp,file.FPP,file.FTNโ fixed form Fortran source code that MUST be preprocessed, using the traditional preprocessor ๐file.f90,file.f95,file.f03,file.f08โ free form Fortran source code that should NOT be preprocessed ๐file.F90,file.F95,file.F03,file.F08โ free form Fortran source code that MUST be preprocessed, using the traditional preprocessor ๐file.goโ Go source code ๐ซงfile.brigโ BRIG files, which are the binary representation of HSAIL ๐คfile.dโ D source code ๐file.diโ D interface file ๐file.ddโ D documentation code (Ddoc) ๐file.adsโ an Ada source file with a library unit declaration (a declaration of a package, subprogram, or generic, or a generic instantiation), or a library unit renaming declaration (a package, generic, or subprogram renaming declaration). these are also called specs ๐file.adbโ an Ada source file containing a library unit body (a subprogram or package body). these are also called bodies ๐file.sโ assembler code ๐งfile.S,file.sxโ assembler code that MUST be preprocessed ๐งotherโ an object file that gets fed straight into linking. any file name with no recognized suffix gets treated this way ๐ซถ
you can also tell GCC the input language yourself with the -x option ๐
-x languageโ tells GCC the language for the input files that come after it, instead of letting it guess from the file name suffix. this applies to every following input file until the next-xshows up. the possible values forlanguageare:
c c-header cpp-output
c++ c++-header c++-cpp-output
objective-c objective-c-header objective-c-cpp-output
objective-c++ objective-c++-header objective-c++-cpp-output
assembler assembler-with-cpp
ada
d
f77 f77-cpp-input f95 f95-cpp-input
go
brig
-x noneโ turns off any language setting, so the files after it get handled by their suffixes, just like they would if-xhad never been used at all ๐งน
if you only want some of the stages, you can use -x (or the filename suffixes) to tell gcc where to start, and one of -c, -S, or -E to say where it should stop ๐ fair warning, some combos (like -x cpp-output -E) make gcc do absolutely nothing ๐
-cโ compile or assemble the source files, but DON'T link ๐ โโ๏ธ the linking stage just isn't done. the final output is one object file per source file. by default, the object file name for a source file gets made by swapping the suffix.c,.i,.s, etc. for.o. unrecognized input files that don't need compilation or assembly get ignored.-Sโ stop after the compilation proper stage, so no assembling ๐ช the output is an assembler code file for each non-assembler input file. by default, the assembler file name for a source file gets made by swapping the suffix.c,.i, etc. for.s. input files that don't need compilation get ignored.-Eโ stop after the preprocessing stage, and don't run the compiler proper ๐ท the output is preprocessed source code, which gets sent to standard output. input files that don't need preprocessing get ignored.-o fileโ put the output infile. this works for whatever you're making, whether it's an executable, an object file, an assembler file, or preprocessed C code ๐ if you don't specify-o, the default is: an executable goes ina.out, the object file forsource.suffixgoes insource.o, its assembler file goes insource.s, a precompiled header goes insource.suffix.gch, and all the preprocessed C source goes to standard output.-vโ prints the commands that get run for each stage of compilation (to standard error). it also prints the version number of the compiler driver, the preprocessor, and the compiler proper ๐ฃ-###โ like-v, except the commands DON'T actually run ๐ arguments get quoted unless they only contain alphanumeric characters or"./-_". this is super handy for shell scripts that want to capture the command lines the driver generates ๐--helpโ prints a description of the command-line optionsgccunderstands (to standard output) ๐ if-vis also specified,--helpgets passed on to the various processesgccinvokes, so they can show the options they accept. and if-Wextrawas specified before--help, options with no documentation get displayed too ๐--target-helpโ prints a description of the target-specific command-line options for each tool (to standard output) ๐ฏ some targets might print extra target-specific info too โจ--help={class|[^]qualifier}[,...]โ okay so this one prints (on the standard output) a rundown of every command-line option the compiler understands that fits all the classes and qualifiers you pick. Here are the classes:optimizersโ every optimization option the compiler supports ๐ฅwarningsโ every option that controls warning messages the compiler produces โ ๏ธtargetโ target-specific options ๐ฏ Unlike--target-help, this one does NOT show the target-specific options of the linker and assembler, because those tools don't currently support the extended--help=syntax ๐paramsโ the values the--paramoption recognizes ๐languageโ options for a language, where language is the name of one of the languages supported in this GCC version. If an option is supported by all languages, you need to pick thecommonclass ๐commonโ the options that are common to all languages โจ
These are the qualifiers:
undocumentedโ only the options that are undocumented ๐ซฃjoinedโ options that take an argument appearing after an equal sign in the same continuous piece of text, like--help=target๐ฆseparateโ options that take an argument appearing as a separate word following the original option, like-o output-file๐
So if you wanna see all the undocumented target-specific switches the compiler supports, just use:
--help=target,undocumented
The sense of a qualifier can be flipped by putting the ^ character in front of it. So if you want all the binary warning options (the ones that are either on or off and don't take an argument) that have a description, use:
--help=warnings,^joined,^undocumented
The argument to --help= should not consist solely of inverted qualifiers. Don't be that person ๐
Combining several classes is possible, but it usually restricts the output so much that there's literally nothing to display. One case where it does work is when one of the classes is target. For example, to display all the target-specific optimization options, use:
--help=target,optimizers
The --help= option can be repeated on the command line. Each successive use displays its requested class of options, skipping the ones that have already been displayed. If --help is also specified anywhere on the command line, then it takes precedence over any --help= option ๐
If the -Q option appears on the command line before the --help= option, the descriptive text displayed by --help= changes! Instead of describing the options, it gives an indication of whether each option is enabled, disabled, or set to a specific value (assuming the compiler knows this at the point where the --help= option is used). Main character energy ๐
Here is a truncated example from the ARM port of gcc:
% gcc -Q -mabi=2 --help=target -c
The following options are target specific:
-mabi= 2
-mabort-on-noreturn [disabled]
-mapcs [disabled]
The output is sensitive to the effects of previous command-line options, so for example you can find out which optimizations are enabled at -O2 by using:
-Q -O2 --help=optimizers
Alternatively, you can discover which binary optimizations are enabled by -O3 by using:
gcc -c -Q -O3 --help=optimizers > /tmp/O3-opts
gcc -c -Q -O2 --help=optimizers > /tmp/O2-opts
diff /tmp/O2-opts /tmp/O3-opts | grep enabled
--versionโ displays the version number and copyrights of the GCC you invoked ๐-pass-exit-codesโ okay so normally thegccprogram exits with the code of1if any phase of the compiler returns a non-success return code. If you specify-pass-exit-codes, though,gccinstead returns with the numerically highest error produced by any phase that returned an error indication. The C, C++, and Fortran front ends return4if they hit an internal compiler error ๐ญ-pipeโ uses pipes rather than temporary files for communication between the various stages of compilation ๐ This fails to work on some systems where the assembler can't read from a pipe, but the GNU assembler has no trouble with it โจ-specs=fileโ processes file after the compiler reads in the standard specs file, to override the defaults thegccdriver uses when deciding which switches to pass tocc1,cc1plus,as,ld, etc. ๐ง You can specify more than one-specs=fileon the command line, and they're processed in order, from left to right.-wrapperโ invokes all subcommands under a wrapper program. The name of the wrapper program and its parameters are passed as a comma separated list. Like this:
gcc -c t.c -wrapper gdb,--args
This invokes all subprograms of gcc under gdb --args, so the invocation of cc1 is gdb --args cc1 .... ๐
-ffile-prefix-map=old=newโ when compiling files living in directory old, any references to them in the result of the compilation get recorded as if the files lived in directory new instead ๐ฆ Specifying this is equivalent to specifying all the individual-f*-prefix-mapoptions, and it can be used to make reproducible builds that are location independent. See also-fmacro-prefix-mapand-fdebug-prefix-map.-fplugin=name.soโ loads the plugin code in file name.so, which is assumed to be a shared object to bedlopen'd by the compiler ๐ The base name of the shared object file is used to identify the plugin for argument parsing (see-fplugin-arg-name-key=valuebelow). Each plugin should define the callback functions specified in the Plugins API.-fplugin-arg-name-key=valueโ defines an argument called key with a value of value for the plugin called name ๐ง-fdump-ada-spec[-slim]โ for C and C++ source and include files, generates corresponding Ada specs ๐-fada-spec-parent=unitโ used together with-fdump-ada-spec[-slim]above, this generates Ada specs as child units of the parent unit ๐ธ-fdump-go-spec=fileโ for input files in any language, generates corresponding Go declarations in file ๐น This makes Goconst,type,var, andfuncdeclarations, which can be a super useful way to start writing a Go interface to code written in some other language.@fileโ reads command-line options from file ๐ The options read are inserted in place of the original@fileoption. If file doesn't exist or can't be read, the option gets treated literally and isn't removed.- Options in file are separated by whitespace. A whitespace character can be included in an option by surrounding the entire option in either single or double quotes.
- Any character (including a backslash) can be included by prefixing it with a backslash.
- The file may itself contain additional
@fileoptions, and any such options will be processed recursively ๐
โจ Compiling C++ Programs โจ
C++ source files conventionally use one of the suffixes .C, .cc, .cpp, .CPP, .c++, .cp, or .cxx. C++ header files often use .hh, .hpp, .H, or (for shared template code) .tcc, and preprocessed C++ files use the suffix .ii. GCC recognizes files with these names and compiles them as C++ programs, even if you call the compiler the same way you would for C programs (usually with the name gcc) ๐
However, using gcc does not add the C++ library. g++ is a program that calls GCC and automatically specifies linking against the C++ library. It treats .c, .h and .i files as C++ source files instead of C source files unless -x is used. This program is also useful when precompiling a C header file with a .h extension for use in C++ compilations. On many systems, g++ is also installed with the name c++ ๐ซถ
When you compile C++ programs, you may specify many of the same command-line options you use for compiling programs in any language, or command-line options meaningful for C and related languages, or options that are meaningful only for C++ programs ๐ฆ
๐ธ Options Controlling C Dialect ๐ธ
The following options control the dialect of C (or languages derived from C, such as C++, Objective-C and Objective-C++) that the compiler accepts:
-ansiโ in C mode, this is equivalent to-std=c90. In C++ mode, it's equivalent to-std=c++98๐- It turns off certain GCC features that are incompatible with ISO C90 (when compiling C code) or standard C++ (when compiling C++ code), like the
asmandtypeofkeywords, and predefined macros such asunixandvaxthat identify the type of system you're using. It also enables the undesirable and rarely used ISO trigraph feature. For the C compiler, it disables recognition of C++ style//comments as well as theinlinekeyword ๐ - The alternate keywords
__asm__,__extension__,__inline__and__typeof__keep working despite-ansi. You wouldn't want to use them in an ISO C program, of course, but they're useful to put in header files that might get included in compilations done with-ansi. Alternate predefined macros such as__unix__and__vax__are also available, with or without-ansi๐ - The
-ansioption does not cause non-ISO programs to be rejected gratuitously. For that,-Wpedanticis required in addition to-ansi๐ - The macro
__STRICT_ANSI__is predefined when the-ansioption is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for, which avoids interfering with any programs that might use those names for other things ๐ง - Functions that are normally built in but don't have semantics defined by ISO C (such as
allocaandffs) are not built-in functions when-ansiis used ๐
- It turns off certain GCC features that are incompatible with ISO C90 (when compiling C code) or standard C++ (when compiling C++ code), like the
-std=โ determines the language standard ๐ This option is currently only supported when compiling C or C++.
Okay so bestie, the -std= flag is where you tell GCC which rulebook to follow ๐โจ GCC can take a base standard like c90 or c++98, or a GNU dialect of one like gnu90 or gnu++98. ๐
With a base standard, GCC accepts every program that follows that standard, plus any GNU extensions that don't clash with it. For example, -std=c90 switches off GCC features that don't fit ISO C90, like the asm and typeof keywords ๐, but keeps other GNU extras that mean nothing in ISO C90, like leaving out the middle term of a ?: expression. โจ
With a GNU dialect, every feature the compiler supports gets turned on, even if that changes what the base standard means ๐ Lowkey this means some strict-conforming programs might get rejected ๐
-Wpedantic uses the chosen standard to decide which features count as GNU extensions. So -std=gnu90 -Wpedantic warns about C++ style // comments, but -std=gnu99 -Wpedantic doesn't. It's giving precision ๐
You must give this option a value. These are the possible values:
c90,c89,iso9899:1990โ Supports all ISO C90 programs. Certain GNU extensions that clash with ISO C90 get disabled. Same as-ansifor C code. ๐ธiso9899:199409โ ISO C90 with amendment 1 added in โจc99,c9x,iso9899:1999,iso9899:199xโ ISO C99 ๐ฆ This one is basically fully supported, aside from bugs and floating-point stuff (mostly, but not entirely, the optional C99 features from Annexes F and G). For more info checkhttp://gcc.gnu.org/c99status.html. The namesc9xandiso9899:199xare deprecated, so maybe don't use them anymore ๐ โโ๏ธc11,c1x,iso9899:2011โ ISO C11, the 2011 revision ๐ Also basically fully supported, aside from bugs and floating-point issues (mostly Annexes F and G again) plus the optional Annexes K (Bounds-checking interfaces) and L (Analyzability). The namec1xis deprecated.c17,c18,iso9899:2017,iso9899:2018โ ISO C17, the 2017 revision (published in 2018) ๐ It's the same as C11 except for defect corrections (all of which also get applied with-std=c11) and a new value of__STDC_VERSION__, so it's supported to the same extent as C11.c2xโ The next version of the ISO C standard, still being worked on ๐ง Support is experimental and incomplete, so be careful bestie.gnu90,gnu89โ GNU dialect of ISO C90, which includes some C99 features ๐gnu99,gnu9xโ GNU dialect of ISO C99. The namegnu9xis deprecated.gnu11,gnu1xโ GNU dialect of ISO C11. The namegnu1xis deprecated.gnu17,gnu18โ GNU dialect of ISO C17. This is the default for C code ๐gnu2xโ The next ISO C standard plus GNU extensions, still in development ๐ง Support is experimental and incomplete.c++98,c++03โ The 1998 ISO C++ standard plus the 2003 technical corrigendum and some extra defect reports. Same as-ansifor C++ code.gnu++98,gnu++03โ GNU dialect of-std=c++98๐c++11,c++0xโ The 2011 ISO C++ standard plus amendments. The namec++0xis deprecated.gnu++11,gnu++0xโ GNU dialect of-std=c++11. The namegnu++0xis deprecated.c++14,c++1yโ The 2014 ISO C++ standard plus amendments. The namec++1yis deprecated.gnu++14,gnu++1yโ GNU dialect of-std=c++14. This is the default for C++ code โจ The namegnu++1yis deprecated.c++17,c++1zโ The 2017 ISO C++ standard plus amendments. The namec++1zis deprecated.gnu++17,gnu++1zโ GNU dialect of-std=c++17. The namegnu++1zis deprecated.c++20,c++2aโ The next revision of ISO C++, planned for 2020 ๐ญ Support is highly experimental and will almost certainly change in incompatible ways in future releases. > Proceed with extreme caution, this one is unstable ๐gnu++20,gnu++2aโ GNU dialect of-std=c++20. Support is highly experimental and will almost certainly change in incompatible ways in future releases. ๐ฅ
๐ -fgnu89-inline
The -fgnu89-inline flag tells GCC to use the old-school GNU rules for inline functions when you're in C99 mode ๐ฐ๏ธ
Using it is roughly the same as slapping the gnu_inline function attribute onto every inline function ๐
-fno-gnu89-inline tells GCC to use the C99 rules for inline when you're in C99 or gnu99 mode. That's the default behavior anyway, so it's kinda redundant lol. This option is not supported in -std=c90 or -std=gnu90 mode.
The preprocessor macros __GNUC_GNU_INLINE__ and __GNUC_STDC_INLINE__ can be used to check which inline semantics are in effect ๐
๐ฆ -fpermitted-flt-eval-methods=style
ISO/IEC TS 18661-3 adds new permissible values for FLT_EVAL_METHOD ๐ธ These say that operations and constants with a semantic type that's an interchange or extended format should be evaluated to the precision and range of that type. The new values are a superset of what C99/C11 allows, and C99/C11 doesn't define what any other positive values mean. So code that's C11-conforming might not have been written with the new values in mind ๐
-fpermitted-flt-eval-methods decides whether the compiler allows only the FLT_EVAL_METHOD values from C99/C11, or the extended set from ISO/IEC TS 18661-3.
style is either c11 or ts-18661-3, whichever fits ๐ซถ
The default in a standards-compliant mode (-std=c11 or similar) is -fpermitted-flt-eval-methods=c11. The default in a GNU dialect (-std=gnu11 or similar) is -fpermitted-flt-eval-methods=ts-18661-3.
๐ -aux-info filename
This dumps prototyped declarations for all functions declared and/or defined in a translation unit into the given filename ๐๏ธ That includes functions in header files too. It's silently ignored in any language other than C, so don't stress if you're doing C++ ๐
Besides the declarations, the file uses comments to show where each declaration came from (source file and line). It also shows whether the declaration was implicit, prototyped or unprototyped. That's marked by I for new (implicit), N for new (prototyped), or O for old (unprototyped), in the first character after the line number and colon. The following character tells you whether it came from a declaration (C) or a definition (F). For function definitions, a K&R-style list of arguments followed by their declarations is also included, inside comments, right after the declaration ๐
Heads up: theI,NandOmarkers are described in the original as "I, N for new or O for old", soIandNboth count as "new" andOis "old." Read it carefully bestie ๐ค
โจ -fallow-parameterless-variadic-functions
This lets you accept variadic functions without named parameters ๐ฆ
You can define one of these, but it's not super useful because you can't read the arguments. This is only supported for C, because C++ allows this construct already ๐
๐ -fno-asm
This stops GCC from treating asm, inline or typeof as keywords, so your code can use those words as identifiers ๐ง Instead, you use the keywords __asm__, __inline__ and __typeof__. -ansi implies -fno-asm.
In C++, this switch only affects the typeof keyword, since asm and inline are standard keywords there. You might want to use -fno-gnu-keywords instead, which has the same effect ๐
In C99 mode (-std=c99 or -std=gnu99), this switch only affects the asm and typeof keywords, because inline is a standard keyword in ISO C99 ๐ธ
๐งฎ -fno-builtin, -fno-builtin-function
This means "don't recognize built-in functions that don't start with the prefix __builtin_" ๐
โโ๏ธ
Normally GCC generates special code for certain built-in functions so they run faster. For example, calls to alloca might turn into single instructions that adjust the stack directly, and calls to memcpy might become inline copy loops ๐ฅ The result is usually smaller and faster, BUT the function calls don't show up as calls anymore. So you can't set a breakpoint on them, and you can't change what they do by linking against a different library ๐ Also, when GCC recognizes a built-in, it might use what it knows about that function to warn you about problems with calls to it, or to generate more efficient code, even if the code still has calls to that function in it. For example, you get warnings with -Wformat for bad calls to printf when printf is built in and strlen is known not to modify global memory ๐ง
With -fno-builtin-function, only that one built-in function gets disabled. The function name must not begin with __builtin_. If you name a function that isn't built in for this version of GCC, the option is just ignored ๐ซ There's no matching -fbuiltin-function option. If you want to enable built-in functions selectively while using -fno-builtin or -ffreestanding, you can define macros like this:
#define abs(n) __builtin_abs ((n))
#define strcpy(d, s) __builtin_strcpy ((d), (s))
๐งช -fgimple
This enables parsing of function definitions marked with __GIMPLE. It's an experimental feature that lets you unit test GIMPLE passes ๐ฌ
๐ -fhosted
This asserts that compilation targets a hosted environment, and it implies -fbuiltin. A hosted environment is one where the entire standard library is available, and where main has a return type of int ๐ Examples are basically everything except a kernel. This is equivalent to -fno-freestanding.
๐ -ffreestanding
This asserts that compilation targets a freestanding environment, and it implies -fno-builtin. In a freestanding environment, the standard library may not exist, and program startup may not necessarily be at main ๐ The most obvious example is an OS kernel. This is equivalent to -fno-hosted.
-fopenaccโ okay so this one switches on handling of OpenACC directives,#pragma accin C/C++ and!$accin Fortran ๐ With it on, the compiler generates accelerated code following the OpenACC Application Programming Interface v2.6 (https://www.openacc.org) โจ It also implies-pthread, so it only works on targets that support-pthread๐-fopenacc-dim=geomโ sets default compute dimensions for parallel offload regions that don't specify their own ๐ฆgeomis a triple of sizes separated by':', in the ordergang,workerandvector. You can leave any size out to use a target-specific default ๐ธ-fopenmpโ enables OpenMP directives,#pragma ompin C/C++ and!$ompin Fortran ๐ With it on, the compiler generates parallel code according to the OpenMP Application Program Interface v4.5 (https://www.openmp.org). It implies-pthread, so it's only supported on targets with-pthreadsupport. It also implies-fopenmp-simd๐-fopenmp-simdโ handles only OpenMP's SIMD directives, written as#pragma ompin C/C++ and!$ompin Fortran. Every other OpenMP directive gets ignored ๐-fgnu-tmโ when this is specified, the compiler generates code for the Linux variant of Intel's current Transactional Memory ABI specification document (Revision 1.1, May 6 2009). It's an experimental feature, so its interface may change in future GCC versions as the official specification changes ๐งช Also, not every architecture supports it, so check before you rely on it ๐
For more information on GCC's support for transactional memory,
๐ Heads up: the transactional memory feature is not supported with non-call exceptions (-fnon-call-exceptions).
-fms-extensionsโ accepts some non-standard constructs used in Microsoft header files ๐ In C++ code, this lets member names in structures match previous type declarations, like this:
typedef int UOW;
struct ABC {
UOW UOW;
};
Some cases of unnamed fields in structures and unions are only accepted with this option โจ Also, this option is off for all targets except x86 targets using ms-abi.
-fplan9-extensionsโ accepts some non-standard constructs used in Plan 9 code ๐ง This turns on-fms-extensionsand lets you pass pointers to structures with anonymous fields to functions that expect pointers to elements of the field's type. It also lets you refer to anonymous fields declared using a typedef. This is only supported for C, not C++ ๐ฆ-fcond-mismatchโ allows conditional expressions with mismatched types in the second and third arguments. The value of such an expression isvoid๐ This option isn't supported for C++.-flax-vector-conversionsโ allows implicit conversions between vectors with differing numbers of elements and/or incompatible element types. Please don't use this for new code ๐ญ-funsigned-charโ makes the typecharunsigned, likeunsigned char๐ธ Every kind of machine has a default for whatcharshould be, and it's either likeunsigned charor likesigned char. Ideally a portable program always usessigned charorunsigned charwhen it depends on signedness, but lots of programs were written to use plaincharand expect it to be signed or unsigned depending on the machine they were written for. This option, and its inverse, let you make those programs work with the opposite default ๐ Also,charis always a distinct type from bothsigned charandunsigned char, even though it behaves exactly like one of those two.-fsigned-charโ makes the typecharsigned, likesigned char๐ This is equivalent to-fno-unsigned-char, which is the negative form of-funsigned-char. Likewise,-fno-signed-charis equivalent to-funsigned-char.-fsigned-bitfields,-funsigned-bitfields,-fno-signed-bitfields,-fno-unsigned-bitfieldsโ these control whether a bit-field is signed or unsigned when the declaration doesn't use eithersignedorunsigned๐ By default, such a bit-field is signed, because that's consistent: basic integer types likeintare signed types too โจ-fsso-struct=endiannessโ sets the default scalar storage order of structures and unions to the endianness you pick ๐ The accepted values arebig-endian,little-endianandnative.nativeis the native endianness of the target and is the default. This option isn't supported for C++.
โ ๏ธ Warning: the -fsso-struct switch causes GCC to generate code that is not binary compatible with code generated without it if the specified endianness is not the native endianness of the target. Be careful with this one, bestie ๐ญ
โจ Options Controlling C++ Dialect โจ
This section covers the command-line options that only mean something for C++ programs ๐ You can still use most GNU compiler options no matter what language your program is in. For example, you might compile a file firstClass.C like this:
g++ -g -fstrict-enums -O -c firstClass.C
In this example, only -fstrict-enums is an option meant only for C++ programs. You can use the other options with any language GCC supports ๐ซถ
Some options for compiling C programs, such as -std, are also relevant for C++ programs ๐
Here is a list of options that are only for compiling C++ programs ๐
-fabi-version=nโ uses version n of the C++ ABI ๐ฆ The default is version 0. Version 0 refers to the version that conforms most closely to the C++ ABI specification, so the ABI you get from version 0 will change in different versions of G++ as ABI bugs get fixed ๐ง- Version 1 โ the version of the C++ ABI that first appeared in G++ 3.2.
- Version 2 โ the version of the C++ ABI that first appeared in G++ 3.4, and was the default through G++ 4.9.
- Version 3 โ corrects an error in mangling a constant address as a template argument.
- Version 4 โ first appeared in G++ 4.5 and implements a standard mangling for vector types.
- Version 5 โ first appeared in G++ 4.6 and corrects the mangling of attribute const/volatile on function pointer types, decltype of a plain decl, and use of a function parameter in the declaration of another parameter.
- Version 6 โ first appeared in G++ 4.7 and corrects the promotion behavior of C++11 scoped enums and the mangling of template argument packs, const/static_cast, prefix ++ and --, and a class scope function used as a template argument.
- Version 7 โ first appeared in G++ 4.8 and treats nullptr_t as a builtin type and corrects the mangling of lambdas in default argument scope.
- Version 8 โ first appeared in G++ 4.9 and corrects the substitution behavior of function types with function-cv-qualifiers.
- Version 9 โ first appeared in G++ 5.2 and corrects the alignment of "nullptr_t".
- Version 10 โ first appeared in G++ 6.1 and adds mangling of attributes that affect type identity, such as ia32 calling convention attributes (e.g. stdcall).
- Version 11 โ first appeared in G++ 7 and corrects the mangling of sizeof... expressions and operator names. For multiple entities with the same name within a function, declared in different scopes, the mangling now changes starting with the twelfth occurrence. It also implies
-fnew-inheriting-ctors. - Version 12 โ first appeared in G++ 8 and corrects the calling conventions for empty classes on the x86_64 target and for classes with only deleted copy/move constructors. It accidentally changes the calling convention for classes with a deleted copy constructor and a trivial move constructor.
- Version 13 โ first appeared in G++ 8.2 and fixes the accidental change in version 12 ๐ฉน
- Version 14 โ first appeared in G++ 10 and corrects the mangling of the nullptr expression.
See also -Wabi.
-fabi-compat-version=nโ on targets that support strong aliases, G++ works around mangling changes by creating an alias with the correct mangled name when it defines a symbol with an incorrect mangled name ๐ช This switch picks which ABI version to use for that alias.- With
-fabi-version=0(the default), this defaults to 11 (GCC 7 compatibility). If another ABI version is explicitly selected, this defaults to 0. For compatibility with GCC versions 3.2 through 4.9, use-fabi-compat-version=2. - If this option isn't provided but
-Wabi=nis, that version is used for compatibility aliases. If this option is provided along with-Wabi(without the version), the version from this option is used for the warning.
- With
-fno-access-controlโ turns off all access checking ๐ This switch is mainly useful for working around bugs in the access control code.-faligned-newโ enables support for C++17 "new" of types that need more alignment thanvoid* ::operator new(std::size_t)provides โจ A numeric argument like-faligned-new=32can specify how much alignment (in bytes) that function provides, but few users will need to override the default ofalignof(std::max_align_t). This flag is enabled by default for-std=c++17.-fchar8_t,-fno-char8_tโ enables support forchar8_tas adopted for C++2a ๐ This includes a newchar8_tfundamental type, changes to the types of UTF-8 string and character literals, new signatures for user-defined literals, associated standard library updates, and new__cpp_char8_tand__cpp_lib_char8_tfeature test macros.
This option lets functions be overloaded for ordinary and UTF-8 strings, like so:
int f(const char *); // #1
int f(const char8_t *); // #2
int v1 = f("text"); // Calls #1
int v2 = f(u8"text"); // Calls #2
It also introduces new signatures for user-defined literals:
int operator""_udl1(char8_t);
int v3 = u8'x'_udl1;
int operator""_udl2(const char8_t*, std::size_t);
int v4 = u8"text"_udl2;
template<typename T, T...> int operator""_udl3();
int v5 = u8"text"_udl3;
Okay so bestie, -fchar8_t is where things get a little messy ๐ญ Switching the types of UTF-8 string and character literals causes incompatibilities with ISO C++11 and later standards. Code that is totally fine under ISO C++11 becomes ill-formed once -fchar8_t is specified. Check out these little heartbreakers ๐
char ca[] = u8"xx"; // error: char-array initialized from wide
// string
const char *cp = u8"xx";// error: invalid conversion from
// `const char8_t*' to `const char*'
int f(const char*);
auto v = f(u8"xx"); // error: invalid conversion from
// `const char8_t*' to `const char*'
std::string s{u8"xx"}; // error: no matching function for call to
// `std::basic_string<char>::basic_string()'
using namespace std::literals;
s = u8"xx"s; // error: conversion from
// `basic_string<char8_t>' to non-scalar
// type `basic_string<char>' requested
โจ OPTIONS โจ
-fcheck-newโ ๐ Checks that the pointer returned byoperator newis non-null before you touch the storage it allocated. Honestly this check is usually unnecessary, because the C++ standard saysoperator newonly returns 0 if it's declaredthrow(), and in that case the compiler always checks the return value even without this option. In every other case, whenoperator newhas a non-empty exception specification, memory exhaustion is signalled by throwingstd::bad_alloc. See also new (nothrow). ๐-fconcepts,-fconcepts-tsโ ๐ฆ Below-std=c++2a,-fconceptsturns on support for the C++ Extensions for Concepts Technical Specification, ISO 19217 (2015).- With
-std=c++2aand above, Concepts are part of the language standard, so-fconceptsdefaults to on. But the standard version of Concepts is very different from the TS, so some constructs that were allowed in the TS but didn't make it into the standard can still be enabled with-fconcepts-ts. ๐ง
- With
-fconstexpr-depth=nโ ๐ธ Sets the maximum nested evaluation depth for C++11 constexpr functions ton. We need a limit so endless recursion can be caught during constant expression evaluation. The minimum the standard requires is 512.-fconstexpr-cache-depth=nโ ๐ Sets the maximum level of nested evaluation depth for C++11 constexpr functions that get cached, ton. It's a heuristic that trades compilation speed (when the cache avoids repeated calculations) against memory use (when the cache gets huge from super recursive evaluations). The default is 8. Very few people need to change it, but if your code does heavy constexpr calculations, feel free to experiment and see which value works best for you. ๐ซถ-fconstexpr-loop-limit=nโ ๐ Sets the maximum number of iterations for a loop in C++14 constexpr functions ton. The limit exists so infinite loops can be caught during constant expression evaluation. The default is 262144 (1<<18).-fconstexpr-ops-limit=nโ ๐งฎ Sets the maximum number of operations during a single constexpr evaluation. Even if one loop's iterations are capped by the limit above, you can still get trouble. If there are several nested loops that each run a lot of times but stay under that limit, or if a loop body (or code outside any loop) needs way too many expressions evaluated, the constexpr evaluation might take forever. The default is 33554432 (1<<25).-fcoroutinesโ ๐งช Enables support for the C++ coroutines extension. It's experimental, so handle with care, bestie โจ-fno-elide-constructorsโ ๐ซ The C++ standard lets an implementation skip creating a temporary that's only used to initialize another object of the same type. This option turns that optimization off and forces G++ to call the copy constructor in every case. It also makes G++ call trivial member functions that would otherwise get expanded inline.- In C++17 the compiler is required to skip these temporaries, but this option still affects trivial member functions. ๐
-fno-enforce-eh-specsโ ๐ Doesn't generate code that checks for violations of exception specifications at run time. This option breaks the C++ standard, but it can be handy for shrinking code size in production builds, kind of like definingNDEBUG.
This does NOT give your code permission to throw exceptions that break the exception specifications. The compiler still optimizes based on those specs, so throwing an unexpected exception causes undefined behavior at run time. Not it. ๐
-fextern-tls-init,-fno-extern-tls-initโ ๐งต The C++11 and OpenMP standards letthread_localandthreadprivatevariables have dynamic (runtime) initialization. To make that work, any use of such a variable goes through a wrapper function that does the necessary initialization. When the use and the definition are in the same translation unit, that overhead can be optimized away. But when the use is in a different translation unit, there's a lot of overhead even if the variable never actually needs dynamic initialization. If you can be sure that no use of the variable in a non-defining TU needs to trigger dynamic initialization (either because the variable is statically initialized, or because a use in the defining TU will run before any uses in another TU), you can skip that overhead with-fno-extern-tls-init.- On targets that support symbol aliases, the default is
-fextern-tls-init. ๐ - On targets that don't support symbol aliases, the default is
-fno-extern-tls-init. ๐
- On targets that support symbol aliases, the default is
-fno-gnu-keywordsโ ๐ค Stopstypeoffrom being treated as a keyword, so you can use that word as an identifier. You can use the keyword__typeof__instead. This option is implied by the strict ISO C++ dialects:-ansi,-std=c++98,-std=c++11, etc.-fno-implicit-templatesโ ๐ โโ๏ธ Never emits code for non-inline templates that get instantiated implicitly (i.e. by use). Only explicit instantiations get code. If you use this option, you have to structure your code so it includes all the explicit instantiations you need, or you'll end up with undefined symbols at link time.-fno-implicit-inline-templatesโ ๐ซง Doesn't emit code for implicit instantiations of inline templates either. By default, inlines are handled differently so that builds with and without optimization need the same set of explicit instantiations.-fno-implement-inlinesโ ๐ฆ To save space, doesn't emit out-of-line copies of inline functions controlled by#pragma implementation. Heads up: this causes linker errors if those functions aren't inlined everywhere they're called.-fms-extensionsโ ๐ช DisablesWpedanticwarnings about constructs used in MFC, like implicit int and getting a pointer to a member function via non-standard syntax.-fnew-inheriting-ctorsโ ๐งฌ Enables the P0136 adjustment to the semantics of C++11 constructor inheritance. It's part of C++17, but it's also considered a Defect Report against C++11 and C++14. This flag is on by default unless-fabi-version=10or lower is specified.-fnew-ttp-matchingโ ๐ญ Enables the P0522 resolution to Core issue 150, which covers template template parameters and default arguments. It allows a template with default template arguments to be passed as an argument for a template template parameter with fewer template parameters. This flag is on by default for-std=c++17.-fno-nonansi-builtinsโ ๐ท Disables built-in declarations of functions that aren't mandated by ANSI/ISO C. These includeffs,alloca,_exit,index,bzero,conjf, and other related functions.-fnothrow-optโ โก Treats athrow()exception specification as if it were anoexceptspecification, which can reduce or remove the text size overhead compared to a function with no exception specification. If the function has local variables of types with non-trivial destructors, the exception specification can actually make the function smaller, because the EH cleanups for those variables can be optimized away.- The semantic effect is that an exception thrown out of a function with this kind of exception specification results in a call to
terminaterather thanunexpected. ๐ฌ
- The semantic effect is that an exception thrown out of a function with this kind of exception specification results in a call to
-fno-operator-namesโ โ Doesn't treat the operator name keywordsand,bitand,bitor,compl,not,orandxoras synonyms as keywords.-fno-optional-diagsโ ๐ Disables diagnostics that the standard says a compiler doesn't need to issue. Right now, the only one G++ issues in this category is the one for a name having multiple meanings within a class.-fpermissiveโ ๐ Downgrades some diagnostics about nonconformant code from errors to warnings. So using-fpermissivelets some nonconforming code compile. Lowkey a cheat code, but use it wisely ๐ซถ-fno-pretty-templatesโ ๐๏ธ When an error message points at a specialization of a function template, the compiler normally prints the template's signature, followed by the template arguments and any typedefs or typenames in the signature (e.g.void f(T) [with T = int]rather thanvoid f(int)). That way it's clear which template is involved. When an error message points at a specialization of a class template, the compiler leaves out any template arguments that match the default template arguments for that template. If either of these behaviors makes the error message harder to understand instead of easier, you can use-fno-pretty-templatesto turn them off. ๐ง-fno-rttiโ ๐ช Disables generating the info for every class with virtual functions that the C++ run-time type identification features use (dynamic_castandtypeid). If you don't use those parts of the language, this flag can save you some space. Exception handling uses the same information, but G++ generates it as needed. Thedynamic_castoperator can still be used for casts that don't need run-time type information, i.e. casts tovoid *or to unambiguous base classes.
Mixing code compiled with-frttiwith code compiled with-fno-rttimay not work. For example, programs may fail to link if a class compiled with-fno-rttiis used as a base for a class compiled with-frtti. Be careful, bestie ๐จ
โจ OPTIONS โจ (continued) ๐
-fsized-deallocationโ okay, this one is giving "upgrade your delete" ๐๏ธโจ It switches on the built-in global declarations below, which showed up in C++14:
void operator delete (void *, std::size_t) noexcept;
void operator delete[] (void *, std::size_t) noexcept;
This is super useful if you write your own replacement deallocation functions that use the object's size to make freeing stuff faster ๐๏ธ๐จ. It's enabled by default under -std=c++14 and above. And -Wsized-deallocation will warn you about spots that might want to add a definition ๐.
-fstrict-enumsโ this lets the compiler optimize based on the assumption that an enum value can only be one of its enumerators ๐ง . (Per the C++ standard, basically: a value that fits in the minimum number of bits needed to represent all the enumerators.) โ ๏ธ That assumption may not hold if your program casts some random integer into the enumerated type, so be careful, bestie.-fstrong-eval-orderโ evaluates member access, array subscripting, and shift expressions left-to-right, and assignment right-to-left, the way it was adopted for C++17 ๐. It's enabled by default with-std=c++17. Then there's-fstrong-eval-order=some, which only orders member access and shift expressions. That one is the default without-std=c++17๐ธ.-ftemplate-backtrace-limit=nโ sets how many template instantiation notes you get for a single warning or error ton. The default is10๐.-ftemplate-depth=nโ sets the max instantiation depth for template classes ton. This limit is what catches endless recursion during template class instantiation ๐. ANSI/ISO C++ conforming programs must not rely on a depth greater than17(it went up to1024in C++11). The default is900, because the compiler can run out of stack space before it hits1024in some situations ๐ญ.-fno-threadsafe-staticsโ skips the extra code that uses the C++ ABI routines for thread-safe initialization of local statics ๐งต. If your code doesn't need to be thread-safe, this can shave a bit off the code size ๐ฆ.-fuse-cxa-atexitโ registers destructors for objects with static storage duration with the"__cxa_atexit"function instead of"atexit"โจ. This is required for fully standards-compliant handling of static destructors, but it only works if your C library supports"__cxa_atexit".-fno-use-cxa-get-exception-ptrโ tells GCC not to use the"__cxa_get_exception_ptr"runtime routine ๐ โโ๏ธ. This makes"std::uncaught_exception"incorrect, but it's necessary if that runtime routine isn't available.-fvisibility-inlines-hiddenโ this switch is you telling GCC that you don't compare pointers to inline functions or methods when the two functions' addresses are taken in different shared objects ๐ค.
Soooo GCC may effectively mark inline methods with __attribute__ ((visibility ("hidden"))), which means they don't show up in a DSO's export table and don't need a PLT indirection when used inside the DSO ๐. Turning this on can have a dramatic effect on load and link times of a DSO, because it massively shrinks the dynamic export table when the library leans heavily on templates ๐.
It's not exactly the same as marking methods hidden directly, though. It doesn't affect static variables local to the function, and it doesn't make the compiler deduce that the function is defined in only one shared object ๐ง.
You can give a method explicit visibility to cancel out the switch for that method. For example, if you do want to compare pointers to a particular inline method, mark it as having default visibility. Marking the enclosing class with explicit visibility has no effect ๐ .
Explicitly instantiated inline methods are unaffected by this option, since their linkage might otherwise cross a shared library boundary ๐ซถ.
-fvisibility-ms-compatโ this one tries to use visibility settings to make GCC's C++ linkage model match Microsoft Visual Studio's ๐. It makes these changes to GCC's linkage model:
- It sets the default visibility to
hidden, like-fvisibility=hidden. - Types, but not their members, are not hidden by default.
- The One Definition Rule gets relaxed for types without explicit visibility specifications that are defined in more than one shared object. Those declarations are permitted if they'd be permitted without this option.
In new code, it's better to use -fvisibility=hidden and export only the classes you actually want externally visible ๐. Unfortunately, code might rely (perhaps accidentally) on the Visual Studio behavior ๐ฌ.
Among the consequences: static data members of the same type, with the same name, defined in different shared objects are different, so changing one doesn't change the other. And pointers to function members defined in different shared objects may not compare equal.
โ ๏ธ Heads up: when this flag is given, defining types with the same name differently is a violation of the ODR. Don't do it!
-fno-weakโ tells G++ not to use weak symbol support, even if the linker provides it ๐ โโ๏ธ. By default, G++ uses weak symbols when they're available. This option exists only for testing and should not be used by end-users. It results in inferior code and has no benefits ๐. It may be removed in a future release of G++.-fext-numeric-literals(C++ and Objective-C++ only) โ accepts imaginary, fixed-point, or machine-defined literal number suffixes as GNU extensions ๐. When this option is turned off, those suffixes are treated as C++11 user-defined literal numeric suffixes. It's on by default for all pre-C++11 dialects and all GNU dialects:-std=c++98,-std=gnu++98,-std=gnu++11,-std=gnu++14. It's off by default for ISO C++11 onwards (-std=c++11, ...).-nostdinc++โ skips the standard directories specific to C++ when searching for header files ๐, but still searches the other standard directories. (This option is used when building the C++ library.)
In addition, these warning options have meanings only for C++ programs ๐ธ:
-Wabi-tag(C++ and Objective-C++ only) โ warns when a type with an ABI tag is used in a context that doesn't have that ABI tag ๐ท๏ธ. See C++ Attributes for more info about ABI tags.-Wcomma-subscript(C++ and Objective-C++ only) โ warns about uses of a comma expression inside a subscripting expression ๐. This usage was deprecated in C++2a. However, a comma expression wrapped in( )is not deprecated. Example:
void f(int *a, int b, int c) {
a[b,c]; // deprecated
a[(b,c)]; // OK
}
It's enabled by default with -std=c++2a.
-Wctor-dtor-privacy(C++ and Objective-C++ only) โ warns when a class seems unusable because all its constructors or destructors are private, and it has neither friends nor public static member functions ๐. It also warns if there are no non-private methods and there's at least one private member function that isn't a constructor or destructor.-Wdelete-non-virtual-dtor(C++ and Objective-C++ only) โ warns whendeleteis used to destroy an instance of a class that has virtual functions and a non-virtual destructor ๐ฅ. It's unsafe to delete a derived class instance through a base class pointer when the base class doesn't have a virtual destructor. This warning is enabled by-Wall.-Wdeprecated-copy(C++ and Objective-C++ only) โ warns that the implicit declaration of a copy constructor or copy assignment operator is deprecated when the class has a user-provided copy constructor or copy assignment operator, in C++11 and up ๐. This warning is enabled by-Wextra. With-Wdeprecated-copy-dtor, it also deprecates the implicit copy if the class has a user-provided destructor.-Wno-init-list-lifetime(C++ and Objective-C++ only) โ turns off the warning about uses ofstd::initializer_listthat are likely to result in dangling pointers ๐ซ . The underlying array for aninitializer_listis handled like a normal C++ temporary object, so it's really easy to accidentally keep a pointer to the array past the end of its lifetime. For example:- If a function returns a temporary
initializer_list, or a localinitializer_listvariable, the array's lifetime ends at the end of the return statement, so the returned value has a dangling pointer ๐ฑ. - If a new-expression creates an
initializer_list, the array only lives until the end of the enclosing full-expression, so theinitializer_liston the heap has a dangling pointer. - When an
initializer_listvariable is assigned from a brace-enclosed initializer list, the temporary array created for the right side only lives until the end of the full-expression. So at the next statement, theinitializer_listvariable has a dangling pointer.
// li's initial underlying array lives as long as li
std::initializer_list<int> li = { 1,2,3 };
// assignment changes li to point to a temporary array
li = { 4, 5 };
// now the temporary is gone and li has a dangling pointer
int i = li.begin()[0] // undefined behavior
- When a list constructor stores the
beginpointer from theinitializer_listargument, that doesn't extend the lifetime of the array. So if a class variable is constructed from a temporaryinitializer_list, the pointer is left dangling by the end of the variable declaration statement ๐. -Wno-literal-suffix(C++ and Objective-C++ only) โ stops the warning when a string or character literal is followed by a ud-suffix that doesn't begin with an underscore ๐ง. As a conforming extension, GCC treats those suffixes as separate preprocessing tokens so that old code using formatting macros from<inttypes.h>keeps working. For example:
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdio.h>
The first part is the PRId64 example, so this one starts just after that. Here's what comes next. Keep those bits in mind, bestie ๐
int main() {
int64_t i64 = 123;
printf("My int64: %" PRId64"\n", i64);
}
Okay so in this case, PRId64 gets treated as its own separate preprocessing token ๐ง no cap, it's giving very specific vibes.
This option also keeps an eye on user-defined literal operators that get declared with a literal suffix identifier which doesn't start with an underscore. Those suffixes are reserved for future standardization, so the warning is literally there to protect you ๐ก๏ธโจ
These warnings are enabled by default. ๐
๐ -Wno-narrowing (C++ and Objective-C++ only)
Okay so for C++11 and later, narrowing conversions are diagnosed by default, because the standard says so ๐ญ A narrowing conversion from a constant throws an error, and a narrowing conversion from a non-constant throws a warning. -Wno-narrowing is the one that mutes that diagnostic ๐ Just know it doesn't change what well-formed code means. Narrowing conversions are still ill-formed in SFINAE contexts, so don't get it twisted.
With -Wnarrowing in C++98, you get a warning when a narrowing conversion that C++11 prohibits happens inside { }, for example:
int i = { 2.2 }; // error: narrowing from double to int
This flag is included in -Wall and -Wc++11-compat โจ
๐ฆ -Wnoexcept (C++ and Objective-C++ only)
Warn when a noexcept-expression evaluates to false because of a call to a function that doesn't have a non-throwing exception specification (so, throw() or noexcept), but the compiler still knows for sure that it never throws. It's giving "technically not promised, but actually fine" energy ๐
๐ธ -Wnoexcept-type (C++ and Objective-C++ only)
Warn if the C++17 feature that makes noexcept part of a function type changes the mangled name of a symbol compared to C++14. It's enabled by -Wabi and -Wc++17-compat ๐
Here's the example, it's so iconic:
template <class T> void f(T t) { t(); };
void g() noexcept;
void h() { f(g); }
In C++14, f calls f<void(*)()>, but in C++17 it calls f<void(*)()noexcept> ๐
๐ง -Wclass-memaccess (C++ and Objective-C++ only)
Warn when the destination of a call to a raw memory function, like memset or memcpy, is an object of class type. This also covers writing into such an object in a way that might bypass a non-trivial or deleted constructor or copy assignment, break const-correctness or encapsulation, or corrupt virtual table pointers. Messing with the representation of these objects can break the invariants the member functions rely on, which is so not it ๐ญ
Here's the main offender. The memset below is undefined because it modifies a non-trivial class object, so it gets flagged:
std::string str = "abc";
memset (&str, 0, sizeof str);
The safe way to initialize or clear storage for these types is to use the appropriate constructor or assignment operator, if one exists ๐ซถ The -Wclass-memaccess option is enabled by -Wall. If you explicitly cast the pointer to the class object to void *, or to a type that the raw memory function can safely access, the warning goes away.
๐ -Wnon-virtual-dtor (C++ and Objective-C++ only)
Warn when a class has virtual functions and an accessible non-virtual destructor, either on itself or on an accessible polymorphic base class. That means it's possible to delete a derived class instance through a pointer to the class or base class, but it's unsafe ๐ This warning is automatically turned on if -Weffc++ is specified.
๐ -Wregister (C++ and Objective-C++ only)
Warn about uses of the register storage class specifier, unless it's part of the GNU Explicit Register Variables extension. The register keyword was deprecated in C++11 and removed in C++17, so it's kinda dead now ๐ It's enabled by default with -std=c++17.
๐ซง -Wreorder (C++ and Objective-C++ only)
Warn when the order of member initializers in the code doesn't match the order they actually have to run in. For example:
struct A {
int i;
int j;
A(): j (0), i (1) { }
};
The compiler rearranges the member initializers for i and j so they match the declaration order of the members, and it emits a warning about that. This warning is enabled by -Wall โจ
๐
-Wno-pessimizing-move (C++ and Objective-C++ only)
This warning goes off when a call to std::move prevents copy elision. A typical case where copy elision can happen is when a function with a class return type returns the name of a non-volatile automatic object. That object can't be a function parameter, and it has to have the same type as the function's return type.
struct T {
...
};
T fn()
{
T t;
...
return std::move (t);
}
In this example, the std::move call is what stops copy elision from happening, which is a whole vibe check ๐
โโ๏ธ
This warning is enabled by -Wall.
๐ -Wno-redundant-move (C++ and Objective-C++ only)
This warning goes off for redundant calls to std::move. That means a move would have happened even without the std::move call. This happens because the compiler is forced to treat an object as an rvalue in certain situations, like returning a local variable where copy elision doesn't apply. Consider:
struct T {
...
};
T fn(T t)
{
...
return std::move (t);
}
Here, the std::move call is redundant ๐ Because G++ implements Core Issue 1579, here's another example:
struct T { // convertible to U
...
};
struct U {
...
};
U fn()
{
T t;
...
return std::move (t);
}
In this example, copy elision isn't applicable because the type of the expression being returned and the function's return type are different. Even so, G++ treats the return value as if it were designated by an rvalue, so yeah, it's still flagged ๐
This warning is enabled by -Wextra.
๐ท -Wredundant-tags (C++ and Objective-C++ only)
Warn about redundant class-key and enum-key in references to class types and enumerated types, in places where the key can be dropped without causing ambiguity. For example:
struct foo;
struct foo *p; // warn that keyword struct can be eliminated
On the other hand, there's no warning in this example:
struct foo;
void foo (); // "hides" struct foo
void bar (struct foo&); // no warning, keyword struct is necessary
๐ง -Wno-subobject-linkage (C++ and Objective-C++ only)
Don't warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage. If a type A depends on a type B with no linkage or internal linkage, then defining it in multiple translation units would be an ODR violation, because the meaning of B differs in each translation unit. If A only appears in a single translation unit, the best way to silence the warning is to give it internal linkage by putting it in an anonymous namespace too. The compiler doesn't give this warning for types defined in the main .C file, since those are unlikely to have multiple definitions. -Wsubobject-linkage is enabled by default ๐ธ
๐ -Weffc++ (C++ and Objective-C++ only)
Warn about violations of these style guidelines from Scott Meyers' Effective C++ series of books ๐ค
- Define a copy constructor and an assignment operator for classes with dynamically-allocated memory.
- Prefer initialization to assignment in constructors.
- Have
operator=return a reference to*this. - Don't try to return a reference when you must return an object.
- Distinguish between prefix and postfix forms of increment and decrement operators.
- Never overload
&&,||, or,.
This option also enables -Wnon-virtual-dtor, which is one of the effective C++ recommendations too. The check is extended to warn about a lack of virtual destructor in accessible non-polymorphic base classes as well.
When you select this option, be aware that the standard library headers don't obey all of these guidelines. Use grep -v to filter out those warnings ๐
๐ -Wstrict-null-sentinel (C++ and Objective-C++ only)
Warn about using an uncasted NULL as a sentinel. When compiling only with GCC, this is a valid sentinel, because NULL is defined as __null. Even though it's a null pointer constant rather than a null pointer, it's guaranteed to be the same size as a pointer. Still, this usage isn't portable across different compilers, so be careful ๐
๐ฃ -Wno-non-template-friend (C++ and Objective-C++ only)
Disable warnings when non-template friend functions are declared within a template. In very old versions of GCC that predate the ISO standard, declarations like friend int foo(int), where the friend's name is an unqualified-id, could be interpreted as a particular specialization of a template function. The warning exists to diagnose compatibility problems, and it's enabled by default.
๐ -Wold-style-cast (C++ and Objective-C++ only)
Warn if an old-style (C-style) cast to a non-void type is used in a C++ program. The new-style casts (dynamic_cast, static_cast, reinterpret_cast, and const_cast) are less vulnerable to unintended effects and way easier to search for ๐
๐ฆ -Woverloaded-virtual (C++ and Objective-C++ only)
Warn when a function declaration hides virtual functions from a base class. For example:
struct A {
virtual void f();
};
struct B: public A {
void f(int);
};
The A class version of f is hidden in B, so code like this:
B* b;
b->f();
fails to compile ๐ญ
๐ฌ -Wno-pmf-conversions (C++ and Objective-C++ only)
Disable the diagnostic for converting a bound pointer to member function to a plain pointer โจ
-Wsign-promo(C++ and Objective-C++ only) โ okay so this one flags it when overload resolution picks a promotion from an unsigned or enumerated type to a signed type, instead of a conversion to an unsigned type of the same size ๐. Older G++ versions tried to keep the unsignedness, but the standard says the current behavior is the way, so that's just the vibe now ๐
-Wtemplates(C++ and Objective-C++ only) โ warns whenever a primary template declaration shows up ๐ฆ. Some coding rules ban templates, so this is how you enforce that rule. It stays quiet inside system headers like the STL, so you can still use the STL, and you can still instantiate or specialize templates โจ
-Wmismatched-tags(C++ and Objective-C++ only) โ warns on declarations of structs, classes, and class templates (plus their specializations) whose class-key doesn't match the definition, or the first declaration if there's no definition ๐ Ngl this one is so specific but also kind of iconic.
Here's the example. The struct Object in the argument list of draw triggers the warning:
class Object {
public:
virtual ~Object () = 0;
};
void draw (struct Object*);
To fix it, either drop the redundant class-key struct, or swap it for class so it matches the definition ๐ซถ Using struct to declare a class isn't wrong, as the example shows. This option is just here to keep your class declarations looking consistent. If your code is meant to be portable to Windows-based compilers, the warning also helps prevent unresolved references, because symbols declared with different class-keys get mangled differently ๐ญ You can use this option on its own or together with -Wredundant-tags.
-Wmultiple-inheritance(C++ and Objective-C++ only) โ warns when a class is defined with multiple direct base classes ๐ธ Same deal as before: some coding rules ban multiple inheritance, so this helps enforce that. It's inactive inside system headers like the STL, and you're still allowed to define classes that indirectly use multiple inheritance ๐ง-Wvirtual-inheritanceโ warns when a class is defined with a virtual direct base class ๐ Some coding rules ban multiple inheritance, so this can enforce that rule. Also inactive inside system headers like the STL, and you can still define classes that indirectly use virtual inheritance โจ-Wno-virtual-move-assignโ silences warnings about inheriting from a virtual base with a non-trivial C++11 move assignment operator. Be careful though, this one is dangerous ๐ If the virtual base is reachable along more than one path, it gets moved multiple times, which can leave both objects in the moved-from state. If your move assignment operator is written so it never moves from a moved-from object, then you can turn this warning off safely ๐ซถ-Wnamespacesโ warns when a namespace definition is opened ๐ Some coding rules ban namespaces, and this helps enforce that. It's inactive inside system headers like the STL, so the STL is still fair game. You can also use using directives and qualified names.-Wno-terminate(C++ and Objective-C++ only) โ turns off the warning about a throw-expression that will immediately result in a call to "terminate" ๐-Wno-class-conversion(C++ and Objective-C++ only) โ doesn't warn when a conversion function converts an object to the same type, to a base class of that type, or to void. Those conversion functions will never be called, so the warning is skipped ๐-Wvolatile(C++ and Objective-C++ only) โ warns about deprecated uses of thevolatilequalifier ๐ That includes:- postfix and prefix
++and--expressions onvolatile-qualified types - simple assignments where the left operand is a
volatile-qualified non-class type, for their value - compound assignments where the left operand is a
volatile-qualified non-class type - a
volatile-qualified function return type - a
volatile-qualified parameter type - structured bindings of a
volatile-qualified type
- postfix and prefix
This usage was deprecated in C++20 ๐ญ It's enabled by default with -std=c++2a.
-Wzero-as-null-pointer-constant(C++ and Objective-C++ only) โ warns when a literal0is used as a null pointer constant. This can be super helpful when you're converting over tonullptrin C++11 ๐ธ
-Waligned-newโ warns about a new-expression of a type that needs greater alignment thanalignof(std::max_align_t), but uses an allocation function without an explicit alignment parameter ๐ฅ This option is enabled by-Wall. Normally it only warns about global allocation functions, but-Waligned-new=allalso warns about class member allocation functions ๐-Wno-placement-new,-Wplacement-new=nโ warns about placement new expressions with undefined behavior, like constructing an object in a buffer that's smaller than the object's type ๐ง For example, this placement new gets diagnosed because it tries to construct an array of 64 integers in a buffer that's only 64 bytes:
char buf [64];
new (buf) int[64];
This warning is enabled by default โจ
-Wplacement-new=1โ this is the default level ๐ At this level, the warning skips some strictly undefined constructs that GCC allows as extensions for compatibility with legacy code. For example, thisnewexpression isn't diagnosed at this level, even though it's undefined according to the C++ standard, because it writes past the end of the one-element array:
struct S { int n, a[1]; };
S *s = (S *)malloc (sizeof *s + 31 * sizeof s->a[0]);
new (s->a)int [32]();
-Wplacement-new=2โ at this level you get all the same diagnostics as level 1, plus one more ๐ It also warns about placement new expressions that construct an object in the last member of a structure, where that member is an array of a single element and the object is bigger than that array. The previous example would get flagged here, but this version uses the flexible member array extension to dodge the warning at level 2:
struct S { int n, a[]; };
S *s = (S *)malloc (sizeof *s + 32 * sizeof s->a[0]);
new (s->a)int [32]();
-Wcatch-value,-Wcatch-value=n(C++ and Objective-C++ only) โ warns about catch handlers that don't catch via reference ๐ Here's how the levels break down:-Wcatch-value=1(or just-Wcatch-value) warns about polymorphic class types that are caught by value-Wcatch-value=2warns about all class types that are caught by value-Wcatch-value=3warns about all types that are not caught by reference
-Wcatch-value is enabled by -Wall ๐ซถ
-Wconditionally-supported(C++ and Objective-C++ only) โ warns for conditionally-supported constructs (C++11[intro.defs]) ๐ฆ-Wno-delete-incomplete(C++ and Objective-C++ only) โ doesn't warn when you delete a pointer to an incomplete type, which can cause undefined behavior at runtime. This warning is enabled by default, so this flag is how you turn it off ๐-Wextra-semi(C++, Objective-C++ only) โ warns about redundant semicolons after in-class function definitions ๐-Wno-inaccessible-base(C++, Objective-C++ only) โ controls warnings for when a base class is inaccessible in a derived class because of ambiguity ๐ This warning is enabled by default. Heads up that the warning for ambiguous virtual bases is turned on by the-Wextraoption instead. Here's the example:
struct A { int a; };
struct B : A { };
struct C : B, A { };
-Wno-inherited-variadic-ctorโ silences warnings about using C++11 inheriting constructors when the base class has a C variadic constructor ๐ง The warning is on by default because the ellipsis doesn't get inherited โจ-Wno-invalid-offsetof(C++ and Objective-C++ only) โ suppresses warnings from applying theoffsetofmacro to a non-POD type ๐ธ According to the 2014 ISO C++ standard, usingoffsetofon a non-standard-layout type is undefined. In existing C++ implementations, though,offsetofusually gives meaningful results. This flag is for folks who know they're writing nonportable code and have deliberately chosen to ignore the warning ๐
The restrictions on offsetof might get relaxed in a future version of the C++ standard ๐
-Wsized-deallocation(C++ and Objective-C++ only) โ warns about a definition of an unsized deallocation function, like these:
void operator delete (void *) noexcept;
void operator delete[] (void *) noexcept;
...without a definition of the matching sized deallocation function:
void operator delete (void *, std::size_t) noexcept;
void operator delete[] (void *, std::size_t) noexcept;
...or vice versa ๐ฅ It's enabled by -Wextra along with -fsized-deallocation.
-Wsuggest-final-typesโ warns about types with virtual methods where the code would be better off if the type were declared with the C++11finalspecifier, or, if possible, declared in an anonymous namespace ๐ That lets GCC devirtualize polymorphic calls more aggressively. This warning works better with link-time optimization, since the class hierarchy graph info is more complete then โญ-Wsuggest-final-methodsโ warns about virtual methods that would benefit from the C++11finalspecifier, or, if possible, having their type declared in an anonymous namespace or with thefinalspecifier ๐ Like the one above, this is more effective with link-time optimization, where the class hierarchy graph is more complete. It's recommended to look at the-Wsuggest-final-typessuggestions first, then rebuild with the new annotations ๐ซถ-Wsuggest-overrideโ warns about overriding virtual functions that aren't marked with theoverridekeyword ๐-Wuseless-cast(C++ and Objective-C++ only) โ warns when an expression is cast to its own type ๐ โจ-Wno-conversion-null(C++ and Objective-C++ only) โ okay so this one tells GCC to stop yelling about conversions betweenNULLand non-pointer types ๐ Heads up that-Wconversion-nullis already on by default, so this is how you opt out ๐
โจ Options Controlling Objective-C and Objective-C++ Dialects โจ
๐ข NOTE: This manual does not describe the Objective-C and Objective-C++ languages themselves. We're here for the flags, bestie ๐ซถ
This section covers the command-line options that only matter for Objective-C and Objective-C++ programs. You can still use most of the language-independent GNU compiler options too, so you could compile a file called some_class.m like this:
gcc -g -fgnu-runtime -O -c some_class.m
In that example, -fgnu-runtime is an Objective-C-only option ๐ธ The other options work with any language GCC supports.
Objective-C is an extension of C, so Objective-C compilations can also use options specific to the C front-end (e.g., -Wtraditional). Same energy for Objective-C++, which can use C++-specific options (e.g., -Wabi) ๐
Here's the list of options that are only for compiling Objective-C and Objective-C++ programs:
-fconstant-string-class=class-nameโ Useclass-nameas the class to instantiate for each literal string written as@"...". The default isNXConstantStringwhen the GNU runtime is in use, andNSConstantStringwhen the NeXT runtime is in use (see below) โจ If-fconstant-cfstringsis also present, it overrides-fconstant-string-classand makes@"..."literals get laid out as constant CoreFoundation strings ๐ฆ-fgnu-runtimeโ Generate object code compatible with the standard GNU Objective-C runtime. This is the default for most types of systems ๐-fnext-runtimeโ Generate output compatible with the NeXT runtime. This is the default for NeXT-based systems, including Darwin and Mac OS X. The macro__NEXT_RUNTIME__is predefined if (and only if) this option is used ๐-fno-nil-receiversโ Assume that every Objective-C message dispatch ([receiver message:arg]) in this translation unit makes sure the receiver is notnil. This lets the runtime use more efficient entry points. It's only available alongside the NeXT runtime and ABI version 0 or 1 ๐ง-fobjc-abi-version=nโ Use versionnof the Objective-C ABI for the selected runtime. Right now this is only supported for the NeXT runtime ๐- Version 0 is the traditional (32-bit) ABI, without support for properties and other Objective-C 2.0 additions.
- Version 1 is the traditional (32-bit) ABI, with support for properties and other Objective-C 2.0 additions.
- Version 2 is the modern (64-bit) ABI.
- If you don't specify anything, the default is Version 0 on 32-bit target machines, and Version 2 on 64-bit target machines.
-fobjc-call-cxx-cdtorsโ For each Objective-C class, GCC checks whether any of its instance variables is a C++ object with a non-trivial default constructor. If so, it synthesizes a special- (id) .cxx_constructinstance method that runs those non-trivial default constructors on the instance variables, in order, and then returnsself๐ซถ It also checks whether any instance variable is a C++ object with a non-trivial destructor, and if so, synthesizes a special- (void) .cxx_destructmethod that runs all of those default destructors in reverse order ๐- The generated
- (id) .cxx_constructand- (void) .cxx_destructmethods only operate on instance variables declared in the current Objective-C class, not the ones inherited from superclasses. It's the Objective-C runtime's job to invoke all of these methods across an object's inheritance hierarchy. - The runtime calls
- (id) .cxx_constructimmediately after a new object instance is allocated, and calls- (void) .cxx_destructimmediately before it deallocates an object instance. - As of this writing, only the NeXT runtime on Mac OS X 10.4 and later can invoke the
- (id) .cxx_constructand- (void) .cxx_destructmethods ๐
- The generated
-fobjc-direct-dispatchโ Allow fast jumps to the message dispatcher. On Darwin, this is accomplished via the comm page โก-fobjc-exceptionsโ Enable syntactic support for structured exception handling in Objective-C, similar to what C++ offers. This option is required to use the Objective-C keywords@try,@throw,@catch,@finallyand@synchronized๐ It's available with both the GNU runtime and the NeXT runtime, but not with the NeXT runtime on Mac OS X 10.2 and earlier ๐-fobjc-gcโ Enable garbage collection (GC) in Objective-C and Objective-C++ programs. This option is only available with the NeXT runtime. The GNU runtime has a different garbage collection implementation that doesn't need special compiler flags โจ-fobjc-nilcheckโ For the NeXT runtime with version 2 of the ABI, check for a nil receiver in method invocations before doing the actual method call. This is the default, and you can turn it off with-fno-objc-nilcheck๐ฆ Class methods and super calls are never checked for nil this way, no matter what this flag is set to. Right now this flag does nothing when the GNU runtime, or an older version of the NeXT runtime ABI, is used ๐ฅ-fobjc-std=objc1โ Conform to the language syntax of Objective-C 1.0, the language recognized by GCC 4.0. This only affects the Objective-C additions to the C/C++ language. It doesn't change conformance to C/C++ standards, which the separate C/C++ dialect option flags control. With this option, any Objective-C syntax that GCC 4.0 doesn't recognize gets rejected. It's super useful if you need to make sure your Objective-C code still compiles with older versions of GCC ๐งธ-freplace-objc-classesโ Emit a special marker that tellsld(1)not to statically link the resulting object file, and letsdyld(1)load it at run time instead. This goes hand in hand with the Fix-and-Continue debugging mode, where the object file might get recompiled and dynamically reloaded during execution, no restart needed ๐ฅ Right now, Fix-and-Continue is only available alongside the NeXT runtime on Mac OS X 10.3 and later ๐ธ-fzero-linkโ When compiling for the NeXT runtime, the compiler normally swaps calls toobjc_getClass("...")(when the class name is known at compile time) for static class references that get initialized at load time, which boosts run-time performance ๐ This flag stops that and keeps theobjc_getClass("...")calls. It's handy in Zero-Link debugging mode, since you can modify individual class implementations while the program is running. The GNU runtime always keeps calls toobjc_get_class("...")no matter which command-line options you pass ๐-fno-local-ivarsโ By default, instance variables in Objective-C can be accessed as if they were local variables inside the methods of the class they're declared in. That can cause shadowing between instance variables and other variables with the same name, either declared locally inside a class method or globally. Specifying-fno-local-ivarsturns this behavior off, so you avoid those shadowing issues ๐ โโ๏ธ-fivar-visibility=[public|protected|private|package]โ Sets the default instance variable visibility to the option you pick, so instance variables declared outside the scope of any access modifier directive default to that visibility ๐-gen-declsโ Dump the interface declarations for all classes seen in the source file to a file namedsourcename.decl๐-Wassign-intercept(Objective-C and Objective-C++ only) โ Warn whenever an Objective-C assignment is intercepted by the garbage collector ๐จ-Wno-property-assign-default(Objective-C and Objective-C++ only) โ Don't warn if a property for an Objective-C object has no assign semantics specified ๐คทโโ๏ธ-Wno-protocol(Objective-C and Objective-C++ only) โ If a class is declared to implement a protocol, GCC warns about every method in that protocol the class doesn't implement. By default, it warns for every method not explicitly implemented in the class, even when the implementation is inherited from the superclass. With-Wno-protocol, methods inherited from the superclass count as implemented, so no warning gets issued for them ๐ง-Wselector(Objective-C and Objective-C++ only) โ Warn if multiple methods of different types for the same selector are found during compilation. This check runs on the list of methods in the final stage of compilation. It also checks each selector that appears in a@selector(...)expression, if a matching method for that selector was found during compilation. Since these checks only scan the method table at the very end, the warnings won't show up if the final stage of compilation isn't reached, for example because an error was found during compilation, or because-fsyntax-onlyis being used ๐ญ-Wstrict-selector-match(Objective-C and Objective-C++ only) โ Warn if multiple methods with differing argument and/or return types are found for a given selector when you try to send a message with that selector to a receiver of typeidorClass. When this flag is off (which is the default), the compiler skips these warnings if the differences are confined to types that share the same size and alignment ๐ท-Wundeclared-selector(Objective-C and Objective-C++ only) โ okay bestie, this one's for Objective-C and Objective-C++ only ๐ It warns you when a@selector(...)expression points at a selector that hasn't been declared yet ๐. A selector counts as undeclared if no method with that name was declared before the@selector(...)shows up. That declaration can be explicit, in an@interfaceor@protocoldeclaration, or implicit, in an@implementationsection. This option runs its checks the moment it spots a@selector(...)expression, while-Wselectorwaits until the final stage of compilation. It also enforces the style rule that methods and selectors must be declared before you use them ๐-print-objc-runtime-infoโ Generates a C header describing the largest structure that gets passed by value, if any ๐ง
โจ Options to Control Diagnostic Messages Formatting โจ
Traditionally, diagnostic messages got formatted without caring about the output device's aspect (e.g. its width, ...) ๐ These options let you control the formatting algorithm, like how many characters go on a line and how often source location info gets reported. Heads up: some language front ends may not honor these options ๐
-fmessage-length=nโ Tries to format error messages so they fit on lines of aboutncharacters. Ifnis zero, no line-wrapping happens and each error message sits on a single line. This is the default for all front ends โจ
Note: this option also affects the display of the#errorand#warningpre-processor directives, and the deprecated function/type/variable attribute. It does not however affect thepragma GCC warningandpragma GCC errorpragmas.
-fdiagnostics-show-location=onceโ Only meaningful in line-wrapping mode ๐ธ This tells the diagnostic reporter to emit source location info once. If a message is too long and has to be wrapped, the location prefix won't get stamped again and again on each continuation line. This is the default behavior.-fdiagnostics-show-location=every-lineโ Only meaningful in line-wrapping mode ๐ฆ This tells the reporter to emit the same source location info as a prefix for every physical line that comes from breaking up a message that's too long to fit on one line.-fdiagnostics-color[=WHEN],-fno-diagnostics-colorโ Uses color in diagnostics ๐WHENisnever,always, orauto. The default depends on how the compiler was configured. It can be any of theWHENoptions above, orneverif theGCC_COLORSenvironment variable isn't present in the environment, andautootherwise.automakes GCC use color only when standard error is a terminal, and when it's not running in an emacs shell. The forms-fdiagnostics-colorand-fno-diagnostics-colorare aliases for-fdiagnostics-color=alwaysand-fdiagnostics-color=never, respectively.
The colors are controlled by the GCC_COLORS environment variable ๐จ Its value is a colon-separated list of capabilities and Select Graphic Rendition (SGR) substrings. SGR commands are interpreted by your terminal or terminal emulator, so check your text terminal's docs for the permitted values and what they mean as character attributes. These substring values are decimal integers that can be stuck together with semicolons. The common ones you'll see are: 1 for bold, 4 for underline, 5 for blink, 7 for inverse, 39 for the default foreground color, 30 to 37 for foreground colors, 90 to 97 for 16-color mode foreground colors, 38;5;0 to 38;5;255 for 88-color and 256-color mode foreground colors, 49 for the default background color, 40 to 47 for background colors, 100 to 107 for 16-color mode background colors, and 48;5;0 to 48;5;255 for 88-color and 256-color mode background colors.
The default GCC_COLORS is:
error=01;31:warning=01;35:note=01;36:range1=32:range2=34:locus=01:\
quote=01:path=01;36:fixit-insert=32:fixit-delete=31:\
diff-filename=01:diff-hunk=32:diff-delete=31:diff-insert=32:\
type-diff=01;32
Here's the decoder ring ๐ 01;31 is bold red, 01;35 is bold magenta, 01;36 is bold cyan, 32 is green, 34 is blue, 01 is bold, and 31 is red. Setting GCC_COLORS to the empty string disables colors. These are the capabilities you can set:
error=โ SGR substring forerror:markers.warning=โ SGR substring forwarning:markers.note=โ SGR substring fornote:markers.path=โ SGR substring for colorizing paths of control-flow events printed via-fdiagnostics-path-format=, like the identifiers of individual events and the lines showing interprocedural calls and returns ๐งญrange1=โ SGR substring for the first additional range.range2=โ SGR substring for the second additional range.locus=โ SGR substring for location info, likefile:lineorfile:line:columnetc.quote=โ SGR substring for info printed within quotes.fixit-insert=โ SGR substring for fix-it hints suggesting text to be inserted or replaced.fixit-delete=โ SGR substring for fix-it hints suggesting text to be deleted.diff-filename=โ SGR substring for filename headers within generated patches.diff-hunk=โ SGR substring for the starts of hunks within generated patches.diff-delete=โ SGR substring for deleted lines within generated patches.diff-insert=โ SGR substring for inserted lines within generated patches.type-diff=โ SGR substring for highlighting mismatching types within template arguments in the C++ frontend ๐-fdiagnostics-urls[=WHEN]โ Uses escape sequences to embed URLs in diagnostics ๐ For example, when-fdiagnostics-show-optionshows the command-line option controlling a diagnostic, it embeds a URL pointing to that option's docs.
WHEN is never, always, or auto. auto makes GCC use URL escape sequences only when standard error is a terminal, and when it's not running in an emacs shell or in any graphical terminal known to be incompatible with this feature (see below).
The default depends on how the compiler was configured. It can be any of the WHEN options above.
GCC can also be configured (via the --with-diagnostics-urls=auto-if-env configure-time option) so the default is affected by environment variables. Under that configuration, GCC defaults to auto if either the GCC_URLS or TERM_URLS environment variables are present and non-empty in the compiler's environment, or to never if neither is.
Even with -fdiagnostics-urls=always, the behavior still depends on those environment variables ๐ญ If GCC_URLS is set to empty or no, URLs don't get embedded in diagnostics. If it's set to st, URLs use ST escape sequences. If it's set to bel, which is the default, URLs use BEL escape sequences. Any other non-empty value enables the feature. If GCC_URLS isn't set, TERM_URLS is used as a fallback.
Note: ST is an ANSI escape sequence, string terminator ESC \. BEL is an ASCII character, CTRL-G, that usually sounds like a beep.
GCC also tries to detect a few terminals that are known to not implement the URL feature, or that have bugs (or had bugs in versions still in use), where URL escapes are likely to misbehave and print garbage on the screen. That list is currently xfce4-terminal, certain known-buggy gnome-terminal versions, the linux console, and mingw. This check can be skipped with -fdiagnostics-urls=always, but do it at your own risk ๐
-fno-diagnostics-show-optionโ By default, each diagnostic emitted includes text indicating the command-line option that directly controls it (if that option is known to the diagnostic machinery). Specifying this flag suppresses that behavior ๐-fno-diagnostics-show-caretโ By default, each diagnostic includes the original source line and a caret^indicating the column. This option suppresses that info ๐ The source line is truncated toncharacters if-fmessage-length=nis given. When the output goes to the terminal, the width is limited to the width given by theCOLUMNSenvironment variable or, if that isn't set, the terminal width.-fno-diagnostics-show-labelsโ By default, when printing source code (via-fdiagnostics-show-caret), diagnostics can label ranges of source code with pertinent info, like the types of expressions ๐ท๏ธ
printf ("foo %s bar", long_i + long_j);
~^ ~~~~~~~~~~~~~~~
| |
char * long int
This option suppresses the printing of those labels (in the example above, the vertical bars and the "char *" and "long int" text).
-fno-diagnostics-show-cweโ Diagnostic messages can optionally have an associated CWE identifier (https://cwe.mitre.org/index.html) ๐ฆ GCC itself only provides that metadata for some-fanalyzerdiagnostics, and GCC plugins may also provide diagnostics with it. By default, if the info is present, it gets printed with the diagnostic. This option suppresses printing that metadata.-fno-diagnostics-show-line-numbersโ By default, when printing source code (via-fdiagnostics-show-caret), a left margin showing line numbers is printed. This option suppresses that left margin ๐-fdiagnostics-minimum-margin-width=widthโ Controls the minimum width of the left margin printed by-fdiagnostics-show-line-numbers. It defaults to6.-fdiagnostics-parseable-fixitsโ Emits fix-it hints in a machine-parseable format, perfect for IDEs ๐งโโ๏ธ For each fix-it, a line gets printed after the relevant diagnostic, starting with the stringfix-it:. For example:
fix-it:"test.c":{45:3-45:21}:"gtk_widget_show_all"
The location is a half-open range ๐ counted in bytes, and the initial column is byte 1, not 0 ๐. In the example up there, bytes 3 through 20 of line 45 of "test.c" get swapped out for the new string:
00000000011111111112222222222
12345678901234567890123456789
gtk_widget_showall (dlg);
^^^^^^^^^^^^^^^^^^
gtk_widget_show_all
Filenames and replacement strings get escaped ๐
. A backslash becomes "\\", a tab becomes "\t", a newline becomes "\n", double quotes become "\"", and non-printable characters get written in octal, so a vertical tab turns into "\013" ๐ธ.
An empty replacement string means the range gets removed ๐๏ธ. An empty range like "45:3-45:3" means the string gets inserted right at that spot โจ.
๐ฉน -fdiagnostics-generate-patch
Okay, this one prints fix-it hints to stderr in unified diff format, after all the diagnostics are printed ๐จ๏ธ. It looks like this:
--- test.c
+++ test.c
@ -42,5 +42,5 @
void show_cb(GtkDialog *dlg)
{
- gtk_widget_showall(dlg);
+ gtk_widget_show_all(dlg);
}
The diff may or may not be colorized, following the same rules as for diagnostics (see -fdiagnostics-color) ๐.
๐ณ -fdiagnostics-show-template-tree
So in the C++ frontend ๐ป, when diagnostics show mismatching template types, you'll see something like:
could not convert 'std::map<int, std::vector<double> >()'
from 'map<[...],vector<double>>' to 'map<[...],vector<float>>
With -fdiagnostics-show-template-tree, you get a tree-like structure showing the common and differing parts of the types, like so:
map<
[...],
vector<
[double != float]>>
The parts that differ are highlighted with color, so "double" and "float" pop in this case ๐ฅ.
๐
โโ๏ธ -fno-elide-type
By default, when the C++ frontend prints mismatching template types ๐, the common parts get squished into "[...]" so the error message isn't a whole novel. For example:
could not convert 'std::map<int, std::vector<double> >()'
from 'map<[...],vector<double>>' to 'map<[...],vector<float>>
Specifying -fno-elide-type suppresses that behavior ๐ซ. It also affects the output of -fdiagnostics-show-template-tree.
๐ค๏ธ -fdiagnostics-path-format=KIND
This one specifies how to print paths of control-flow events for diagnostics that have a path attached to them ๐งญ.
KIND can be none, separate-events, or inline-events, and inline-events is the default โญ.
none means don't print diagnostic paths at all ๐ฅ.
separate-events means each event within the diagnostic gets its own separate "note" diagnostic ๐. For example:
test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter
test.c:25:10: note: (1) when 'PyList_New' fails, returning NULL
test.c:27:3: note: (2) when 'i < count'
test.c:29:5: note: (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
inline-events means the events get printed "inline" right inside the source code ๐ซ. This view tries to consolidate events into runs of events that are close together, then prints them as labelled ranges within the source.
For example, the same events as above might be printed as:
'test': events 1-3
|
| 25 | list = PyList_New(0);
| | ^~~~~~~~~~~~~
| | |
| | (1) when 'PyList_New' fails, returning NULL
| 26 |
| 27 | for (i = 0; i < count; i++) {
| | ~~~
| | |
| | (2) when 'i < count'
| 28 | item = PyLong_FromLong(random());
| 29 | PyList_Append(list, item);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
|
Interprocedural control flow ๐ข is shown by grouping the events by stack frame, and using indentation to show how stack frames are nested, pushed, and popped. For example:
'test': events 1-2
|
| 133 | {
| | ^
| | |
| | (1) entering 'test'
| 134 | boxed_int *obj = make_boxed_int (i);
| | ~~~~~~~~~~~~~~~~~~
| | |
| | (2) calling 'make_boxed_int'
|
+--> 'make_boxed_int': events 3-4
|
| 120 | {
| | ^
| | |
| | (3) entering 'make_boxed_int'
| 121 | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) calling 'wrapped_malloc'
|
+--> 'wrapped_malloc': events 5-6
|
| 7 | {
| | ^
| | |
| | (5) entering 'wrapped_malloc'
| 8 | return malloc (size);
| | ~~~~~~~~~~~~~
| | |
| | (6) calling 'malloc'
|
<-------------+
|
'test': event 7
|
| 138 | free_boxed_int (obj);
| | ^~~~~~~~~~~~~~~~~~~~
| | |
| | (7) calling 'free_boxed_int'
|
(etc)
๐ -fdiagnostics-show-path-depths
This option gives you extra info when printing control-flow paths tied to a diagnostic ๐ต๏ธโโ๏ธ.
If this option is provided, the stack depth gets printed for each run of events within -fdiagnostics-path-format=separate-events ๐.
This one is meant for GCC developers and plugin developers ๐งโ๐ป when they're debugging diagnostics that report interprocedural control flow.
๐ -fno-show-column
Don't print column numbers in diagnostics. This may be necessary if diagnostics are being scanned by a program that doesn't understand the column numbers, such as dejagnu ๐ซถ.
๐งพ -fdiagnostics-format=FORMAT
This picks a different format for printing diagnostics. FORMAT is text or json, and the default is text ๐.
The json format is a top-level JSON array containing JSON objects that represent the diagnostics ๐ง.
The JSON gets emitted as one line with no formatting ๐ต, so the examples below have been formatted to make them readable.
Diagnostics can have child diagnostics ๐ถ. For example, this error and note:
misleading-indentation.c:15:3: warning: this 'if' clause does not
guard... [-Wmisleading-indentation]
15 | if (flag)
| ^~
misleading-indentation.c:17:5: note: ...this statement, but the latter
is misleadingly indented as if it were guarded by the 'if'
17 | y = 2;
| ^
might get printed in JSON form (after formatting) like this:
[
{
"kind": "warning",
"locations": [
{
"caret": {
"column": 3,
"file": "misleading-indentation.c",
"line": 15
},
"finish": {
"column": 4,
"file": "misleading-indentation.c",
"line": 15
}
}
],
"message": "this \u2018if\u2019 clause does not guard...",
"option": "-Wmisleading-indentation",
"option_url": "https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmisleading-indentation",
"children": [
{
"kind": "note",
"locations": [
{
"caret": {
"column": 5,
"file": "misleading-indentation.c",
"line": 17
}
}
],
"message": "...this statement, but the latter is ..."
}
]
},
...
]
where the "note" is a child of the "warning" ๐งธ.
A diagnostic has a "kind" ๐ท๏ธ. If this is "warning", then there is an "option" key describing the command-line option controlling the warning.
A diagnostic can contain zero or more locations ๐. Each location has up to three positions within it: a "caret" position and optional "start" and "finish" positions. A location can also have an optional "label" string. For example, this error:
bad-binary-ops.c:64:23: error: invalid operands to binary + (have 'S' {aka
'struct s'} and 'T' {aka 'struct t'})
64 | return callee_4a () + callee_4b ();
| ~~~~~~~~~~~~ ^ ~~~~~~~~~~~~
| | |
| | T {aka struct t}
| S {aka struct s}
has three locations, bestie ๐ Its main spot is the + token at column 23 โจ. It also has two secondary spots for the left and right sides of the expression, and those two get labels ๐ท๏ธ. If you ask for JSON, it might look like this ๐ง:
{
"children": [],
"kind": "error",
"locations": [
{
"caret": {
"column": 23, "file": "bad-binary-ops.c", "line": 64
}
},
{
"caret": {
"column": 10, "file": "bad-binary-ops.c", "line": 64
},
"finish": {
"column": 21, "file": "bad-binary-ops.c", "line": 64
},
"label": "S {aka struct s}"
},
{
"caret": {
"column": 25, "file": "bad-binary-ops.c", "line": 64
},
"finish": {
"column": 36, "file": "bad-binary-ops.c", "line": 64
},
"label": "T {aka struct t}"
}
],
"message": "invalid operands to binary + ..."
}
Okay, next up: fix-it hints ๐
If a diagnostic has them, it gets a "fixits" array made of half-open intervals, kinda like what you'd get from -fdiagnostics-parseable-fixits. Here's a diagnostic with a replacement fix-it hint:
demo.c:8:15: error: 'struct s' has no member named 'colour'; did you
mean 'color'?
8 | return ptr->colour;
| ^~~~~~
| color
And here's how that might look in JSON form ๐ฆ:
{
"children": [],
"fixits": [
{
"next": {
"column": 21,
"file": "demo.c",
"line": 8
},
"start": {
"column": 15,
"file": "demo.c",
"line": 8
},
"string": "color"
}
],
"kind": "error",
"locations": [
{
"caret": {
"column": 15,
"file": "demo.c",
"line": 8
},
"finish": {
"column": 20,
"file": "demo.c",
"line": 8
}
}
],
"message": "\u2018struct s\u2019 has no member named ..."
}
So the fix-it hint means: replace the text from "start" up to but not including "next" with the value of "string". Deletions are written with an empty "string" value, and insertions are written by having "start" equal "next" โจ.
Control-flow paths ๐ธ If the diagnostic has a path of control-flow events attached, it gets a "path" array of event objects. Each event has a "description" string and a "location" object, plus a "function" string and a "depth" number for showing interprocedural paths. The "function" is the current function at that event, and the "depth" is the stack depth relative to some baseline: the higher the number, the more frames are on the stack ๐ฅ.
For example, the intraprocedural example from -fdiagnostics-path-format= could have this JSON for its path:
"path": [
{
"depth": 0,
"description": "when 'PyList_New' fails, returning NULL",
"function": "test",
"location": {
"column": 10,
"file": "test.c",
"line": 25
}
},
{
"depth": 0,
"description": "when 'i < count'",
"function": "test",
"location": {
"column": 3,
"file": "test.c",
"line": 27
}
},
{
"depth": 0,
"description": "when calling 'PyList_Append', passing NULL from (1) as argument 1",
"function": "test",
"location": {
"column": 5,
"file": "test.c",
"line": 29
}
}
]
โจ Options to Request or Suppress Warnings โจ
Okay, so warnings are diagnostic messages about constructions that aren't straight-up erroneous but are risky, or that suggest there may have been a mistake ๐.
These language-independent options don't turn on any specific warnings. Instead, they control the kinds of diagnostics GCC produces ๐.
-fsyntax-onlyโ checks your code for syntax errors and stops right there. Nothing extra ๐ โโ๏ธ.-fmax-errors=nโ caps the number of error messages at n, and then GCC bails instead of trying to keep going through the source code ๐. If n is0(the default), there's no limit on how many errors get printed. If-Wfatal-errorsis also specified, then-Wfatal-errorstakes precedence over this one ๐.-wโ inhibits all warning messages ๐คซ.-Werrorโ turns every warning into an error ๐ค.-Werror=โ turns one specific warning into an error. You append the warning's name, so for example-Werror=switchmakes the warnings controlled by-Wswitchinto errors ๐ฅ. It also has a negative form, which negates-Werrorfor specific warnings. For example,-Wno-error=switchmeans-Wswitchwarnings are not errors, even when-Werroris in effect ๐ซถ.- Every controllable warning's message includes the option that controls it, and you can use that option with
-Werror=and-Wno-error=like we just talked about. (Printing that option in the message can be turned off with the-fno-diagnostics-show-optionflag ๐.) - Heads up: specifying
-Werror=fooautomatically implies-Wfoo. However,-Wno-error=foodoes not imply anything ๐ง.
- Every controllable warning's message includes the option that controls it, and you can use that option with
-Wfatal-errorsโ makes the compiler abort on the very first error instead of trying to keep going and printing more error messages ๐.
You can request a ton of specific warnings with options that begin with -W. For example, -Wimplicit asks for warnings on implicit declarations ๐. Every one of these specific warning options also has a negative form that starts with -Wno- to turn the warnings off. For example, -Wno-implicit ๐. This manual only lists one of the two forms, whichever one isn't the default. For more language-specific options, also check out C++ Dialect Options and Objective-C and Objective-C++ Dialect Options ๐. Additional warnings can be produced by enabling the static analyzer;
Some options, like -Wall and -Wextra, switch on other options, like -Wunused, which might switch on even more options, like -Wunused-value ๐ง. When you mix positive and negative forms, the more specific option wins over the less specific one, no matter where it sits on the command line. For options with the same specificity, the last one takes effect ๐. Options turned on or off via pragmas act as if they appeared at the very end of the command line ๐.
When you request an unrecognized warning option (like -Wunknown-warning), GCC emits a diagnostic saying the option isn't recognized ๐ค. But if you use the -Wno- form, it's a little different: no diagnostic is produced for -Wno-unknown-warning unless other diagnostics are also being produced. This lets you use new -Wno- options with old compilers ๐ฆ. The catch is that if something goes wrong, the compiler will warn you that an unrecognized option is present โ ๏ธ.
The effectiveness of some warnings depends on optimizations also being enabled. For example, -Wsuggest-final-types works better with link-time optimization, and -Wmaybe-uninitialized doesn't warn at all unless optimization is turned on ๐ง.
-Wpedantic,-pedanticโ issues all the warnings demanded by strict ISO C and ISO C++, and rejects programs that use forbidden extensions, plus some other programs that don't follow ISO C and ISO C++ ๐ง. For ISO C, it follows whichever version of the ISO C standard you specify with any-stdoption you used.- Valid ISO C and ISO C++ programs should compile properly with or without this option, though a rare few need
-ansior a-stdoption specifying the required version of ISO C. Without this option, certain GNU extensions and traditional C and C++ features are supported too. With this option, they get rejected ๐ โโ๏ธ. -Wpedanticdoesn't cause warnings for the alternate keywords whose names begin and end with__. That alternate format can also disable warnings for non-ISO__intNtypes, i.e.__intN__. Pedantic warnings are also disabled in the expression that follows__extension__. Only system header files should use these escape routes, though. Application programs should avoid them ๐ซ.
- Valid ISO C and ISO C++ programs should compile properly with or without this option, though a rare few need
Some people try to use -Wpedantic to check programs for strict ISO C conformance, and then they're shook. It doesn't quite do what they want ๐ญ. It finds some non-ISO practices, but not all โ only the ones ISO C requires a diagnostic for, plus some others that have had diagnostics added ๐
.
A feature that reports every failure to conform to ISO C would be useful sometimes, bestie, but it would be a LOT of extra work and totally different from -Wpedantic ๐ญ No plans to add it anytime soon.
Where the standard set with -std is a GNU extended dialect like gnu90 or gnu99, there's a matching base standard, the version of ISO C that dialect is built on ๐ธ -Wpedantic warnings show up wherever that base standard requires them. It wouldn't make sense for warnings to appear only for features outside the GNU dialect you picked, because the GNU dialects already include every feature the compiler supports with that option, so there'd be nothing left to warn about ๐
๐
-pedantic-errors
This one turns the base standard's required diagnostics into full-on errors ๐ฅ It also covers some cases with undefined behavior at compile time, plus some other cases that don't stop compilation of programs that are valid under the standard.
Not the same as -Werror=pedantic! This option enables some errors the other one doesn't, and the other way around too ๐
๐ -Wall
This turns on every warning about constructions some users find questionable, the ones that are easy to avoid (or easy to tweak so the warning goes away), even when macros are involved โจ It also switches on some language-specific warnings from the C++ Dialect Options and Objective-C and Objective-C++ Dialect Options sections.
-Wall turns on these warning flags:
-Waddress -Warray-bounds=1 (only with -O2) -Wbool-compare
-Wbool-operation -Wc++11-compat -Wc++14-compat -Wcatch-value (C++ and Objective-C++ only)
-Wchar-subscripts -Wcomment -Wduplicate-decl-specifier (C and Objective-C only)
-Wenum-compare (in C/ObjC; this is on by default in C++) -Wenum-conversion in C/ObjC;
-Wformat -Wformat-overflow -Wformat-truncation -Wint-in-bool-context
-Wimplicit (C and Objective-C only) -Wimplicit-int (C and Objective-C only)
-Wimplicit-function-declaration (C and Objective-C only) -Winit-self (only for C++)
-Wlogical-not-parentheses -Wmain (only for C/ObjC and unless -ffreestanding)
-Wmaybe-uninitialized -Wmemset-elt-size -Wmemset-transposed-args
-Wmisleading-indentation (only for C/C++) -Wmissing-attributes
-Wmissing-braces (only for C/ObjC) -Wmultistatement-macros -Wnarrowing (only for C++)
-Wnonnull -Wnonnull-compare -Wopenmp-simd -Wparentheses
-Wpessimizing-move (only for C++) -Wpointer-sign -Wreorder -Wrestrict -Wreturn-type
-Wsequence-point -Wsign-compare (only in C++) -Wsizeof-pointer-div
-Wsizeof-pointer-memaccess -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch
-Wtautological-compare -Wtrigraphs -Wuninitialized -Wunknown-pragmas
-Wunused-function -Wunused-label -Wunused-value -Wunused-variable
-Wvolatile-register-var -Wzero-length-bounds
Heads up ๐ฆ Some warning flags are not included in -Wall. A few of them flag stuff most people don't think is sus, but you might still want to check for it sometimes. Others flag stuff that's necessary or really hard to avoid in certain cases, with no easy code change to shut them up. Some are turned on by -Wextra, but lots of them have to be enabled one by one.
๐ -Wextra
This enables some extra warning flags that -Wall doesn't ๐ง (This option used to be called -W. The older name still works, but -Wextra is more descriptive, so use that one bestie ๐)
-Wclobbered -Wcast-function-type -Wdeprecated-copy (C++ only)
-Wempty-body -Wignored-qualifiers -Wimplicit-fallthrough=3
-Wmissing-field-initializers -Wmissing-parameter-type (C only)
-Wold-style-declaration (C only) -Woverride-init -Wsign-compare (C only)
-Wstring-compare -Wredundant-move (only for C++) -Wtype-limits
-Wuninitialized -Wshift-negative-value (in C++11 to C++17 and in C99 and newer)
-Wunused-parameter (only with -Wunused or -Wall)
-Wunused-but-set-parameter (only with -Wunused or -Wall)
-Wextra also prints warnings for these cases:
- A pointer gets compared against integer zero with
<,<=,>, or>=. - (C++ only) An enumerator and a non-enumerator both show up in a conditional expression.
- (C++ only) Ambiguous virtual bases.
- (C++ only) Subscripting an array that's been declared "register".
- (C++ only) Taking the address of a variable that's been declared "register".
- (C++ only) A base class doesn't get initialized in the copy constructor of a derived class.
๐ฆ -Wabi (C, Objective-C, C++ and Objective-C++ only)
This warns about code affected by ABI changes ๐ That includes code that might not be compatible with the vendor-neutral C++ ABI, plus the psABI for the particular target.
Since G++ now updates the ABI with every major release by default, -Wabi usually only warns about C++ ABI compatibility problems when a check was added later in a release series for an ABI issue found after the initial release. -Wabi warns about more stuff if you pick an older ABI version (with -fabi-version=n).
You can also give -Wabi an explicit version number to check C++ ABI compatibility against a specific -fabi-version level, like -Wabi=2 to warn about changes relative to -fabi-version=2.
If you give an explicit version number and don't specify -fabi-compat-version, the version number from this option gets used for compatibility aliases. If you don't give a version number with this option but do specify -fabi-compat-version, that version number is used for the C++ ABI warnings โจ
Even though a lot of effort went into warning about every case, there are probably some cases that slip through, even though G++ is generating incompatible code. There can also be cases where warnings pop up even though the generated code is actually compatible ๐
If you're worried that G++ code might not be binary compatible with code from other compilers, rewrite your code to dodge these warnings.
Known incompatibilities in -fabi-version=2 (the default from GCC 3.4 to 4.9) include:
- A template with a non-type template parameter of reference type got mangled incorrectly:
extern int N;
template <int &> struct S {};
void n (S<N>) {2}
This was fixed in -fabi-version=3.
- SIMD vector types declared with
__attribute ((vector_size))were mangled in a non-standard way that didn't allow overloading functions that take vectors of different sizes.
The mangling changed in -fabi-version=4.
__attribute ((const))andnoreturnwere mangled as type qualifiers, anddecltypeof a plain declaration got folded away โ๏ธ
These mangling issues got fixed in -fabi-version=5.
- Scoped enumerators passed as arguments to a variadic function got promoted like unscoped enumerators, causing
va_argto complain. On most targets this doesn't actually change the parameter passing ABI, since there's no way to pass an argument smaller thanint.
The ABI also changed the mangling of template argument packs, const_cast, static_cast, prefix increment/decrement, and a class scope function used as a template argument.
These issues got corrected in -fabi-version=6.
- Lambdas in default argument scope were mangled incorrectly, and the ABI changed the mangling of
nullptr_t.
These issues got corrected in -fabi-version=7.
- When mangling a function type with function-cv-qualifiers, the un-qualified function type was incorrectly treated as a substitution candidate.
This was fixed in -fabi-version=8, the default for GCC 5.1.
decltype(nullptr)incorrectly had an alignment of 1, which led to unaligned accesses. This didn't affect the ABI of a function with anullptr_tparameter, since parameters have a minimum alignment.
This was fixed in -fabi-version=9, the default for GCC 5.2.
- Target-specific attributes that affect the identity of a type, like ia32 calling conventions on a function type (stdcall, regparm, etc.), didn't affect the mangled name. That led to name collisions when function pointers were used as template arguments.
This was fixed in -fabi-version=10, the default for GCC 6.1.
This option also enables warnings about psABI-related changes. The known psABI changes at this point include:
- For SysV/x86-64, unions with
long doublemembers get passed in memory as the psABI specifies. Before GCC 4.4, this wasn't the case. For example:
union U {
long double ld;
int i;
};
union U is now always passed in memory ๐
๐ -Wchar-subscripts
This warns if an array subscript has type char. It's a super common source of bugs, since programmers often forget this type is signed on some machines ๐ This warning is enabled by -Wall.
๐ธ -Wno-coverage-mismatch
This warns if feedback profiles don't match when you use -fprofile-use ๐ If a source file changes between compiling with -fprofile-generate and -fprofile-use, the profile feedback files can fail to match the source, and GCC can't use the profile feedback info.
By default this warning is on and gets treated as an error. You can use -Wno-coverage-mismatch to turn off the warning, or -Wno-error=coverage-mismatch to turn off the error.
Turning off the error can lead to poorly optimized code, and it's only useful for really minor changes, like bug fixes to an existing codebase. Completely disabling the warning is not recommended ๐
๐ง -Wno-cpp
(C, Objective-C, C++, Objective-C++ and Fortran only) This suppresses the warning messages emitted by #warning directives ๐ซถ
-Wdouble-promotion(C, C++, Objective-C and Objective-C++ only) โ okay bestie, this one yells whenever afloatgets quietly promoted to adouble๐. Some CPUs have a 32-bit single-precision FPU that handlesfloatin hardware but has to fakedoublein software, and that fake version is SO expensive. Doing math withdoubleon those machines means paying a whole overhead tax ๐. The sneaky part is that floating-point literals are implicitlydouble, so it's super easy to do it by accident ๐. Check this out:
float area(float radius)
{
return 3.14159 * radius * radius;
}
The compiler does the entire computation in double because that little 3.14159 literal is a double ๐ญ not it, bestie.
-Wduplicate-decl-specifier(C and Objective-C only) โ warns if a declaration repeats aconst,volatile,restrictor_Atomicspecifier ๐ . This one is turned on by-Wallโจ.-Wformat,-Wformat=nโ the big one ๐ This checks calls toprintfandscanf, etc., to make sure the arguments you pass match the types the format string wants, and that the conversions in the format string actually make sense. It covers the standard functions plus anything with format attributes, in theprintf,scanf,strftimeandstrfmonfamilies (strfmonis an X/Open extension, not in the C standard) or other target-specific families ๐ธ. Which functions get checked without format attributes depends on the standard version you picked, and those checks get switched off by-ffreestandingor-fno-builtin๐ซถ.
The formats get checked against the format features supported by GNU libc version 2.2 ๐ฆ. That includes all ISO C90 and C99 features, plus stuff from the Single Unix Specification and some BSD and GNU extensions. Other library implementations might not support all of these, and GCC doesn't warn about features that go beyond a particular library's limits ๐. BUT if you use -Wpedantic along with -Wformat, you'll get warnings about format features that aren't in your selected standard version (not for strfmon formats though, since those aren't in any version of the C standard) โจ.
-Wformat=1,-Wformatโ-Wformatis the same as-Wformat=1, and-Wno-formatis the same as-Wformat=0๐. Since-Wformatalso checks for null format arguments for several functions, it also implies-Wnonnull๐. Some parts of this level can be turned off with-Wno-format-contains-nul,-Wno-format-extra-args, and-Wno-format-zero-length๐.-Wformatis enabled by-Wall๐.-Wformat=2โ turns on-Wformatplus some extra format checks ๐ฅ. Right now that's the same as-Wformat -Wformat-nonliteral -Wformat-security -Wformat-y2k๐ .
-Wno-format-contains-nulโ if-Wformatis on, don't warn about format strings that contain NUL bytes ๐ฆ.-Wno-format-extra-argsโ if-Wformatis on, don't warn about extra arguments to aprintforscanfformat function ๐. The C standard says those extra args just get ignored, so this is the no-drama option ๐ . Now, if the unused arguments sit between used arguments that use$operand number specs, you'll still get warnings by default, because the implementation can't know what type to handva_argto skip them ๐ญ. But forscanfformats, this option does suppress that warning when all the unused arguments are pointers, since the Single Unix Specification says those are allowed ๐ซถ.-Wformat-overflow,-Wformat-overflow=levelโ warns about calls to formatted output functions likesprintfandvsprintfthat might overflow the destination buffer ๐ธ. When the exact number of bytes a format directive writes can't be figured out at compile time, GCC estimates it with heuristics that depend on thelevelargument and on optimization โจ. Turning on optimization usually makes the warning more accurate, but it can also cause false positives ๐. Here's how the levels work:-Wformat-overflow,-Wformat-overflow=1โ level 1 is enabled by-Wformatand is super conservative ๐ซถ. It only warns about calls that most likely overflow the buffer ๐. At this level, numeric args with unknown values are assumed to be one, and strings of unknown length are assumed to be empty ๐ง. Numeric args known to be bounded to a subrange of their type, or string args whose output is bounded by their directive's precision or by a finite set of string literals, are assumed to take whichever value in that range gives the most bytes of output ๐. In the example below, the call tosprintfgets diagnosed because even with bothaandbequal to zero, the terminating NUL character ('\0') that the function appends to the destination buffer gets written past its end ๐ญ. Making the buffer one byte bigger is enough to dodge the warning, though it might not be enough to actually avoid the overflow ๐.
void f (int a, int b)
{
char buf [13];
sprintf (buf, "a = %i, b = %i\n", a, b);
}
-Wformat-overflow=2โ level 2 warns about all of that plus calls that might overflow the buffer given an argument of big enough length or magnitude ๐ฅ. At level 2, unknown numeric args are assumed to have the minimum representable value for signed types with a precision greater than 1, and the maximum representable value otherwise ๐. Unknown string args that can't be assumed bounded by the directive's precision, a finite set of string literals they might evaluate to, or the character array they might point to, are assumed to be 1 character long ๐.
At level 2, the call in the example above gets diagnosed again, but this time it's because with a equal to a 32-bit INT_MIN, the first %i directive writes some of its digits past the end of the destination buffer ๐ญ. To make the call safe no matter what the two variables are, the destination buffer has to be at least 34 bytes โจ. GCC includes that minimum buffer size in an informational note right after the warning ๐ฆ.
You can also shrink the problem instead of growing the buffer: constrain the range of the formatted values ๐
. You can bound the max length of string args by giving a precision in the format directive ๐ธ. And when numeric args can be assumed to be bounded by less than the precision of their type, picking an appropriate length modifier in the format specifier (or casting the argument) will reduce the required buffer size ๐ง. In the example below, if a and b are within the precision of short int, then using the %hi directive or casting the argument to short drops the max required buffer size down to 24 bytes ๐ซถ.
void f (int a, int b)
{
char buf [23];
sprintf (buf, "a = %hi, b = %i\n", a, (short)b);
}
-Wno-format-zero-lengthโ if-Wformatis on, don't warn about zero-length formats ๐. The C standard says zero-length formats are allowed, so GCC won't yell about them ๐.-Wformat-nonliteralโ if-Wformatis on, also warn if the format string isn't a string literal, since then it can't be checked ๐. The exception is when the format function takes its format arguments as ava_list๐ธ.-Wformat-securityโ if-Wformatis on, also warn about uses of format functions that could be security problems ๐. Right now this warns about calls toprintfandscanfwhere the format string isn't a string literal and there are no format arguments, likeprintf (foo);๐ฌ. That can be a security hole if the format string came from untrusted input and contains%n๐. (Currently this is a subset of what-Wformat-nonliteralwarns about, but future warnings might get added to-Wformat-securitythat aren't in-Wformat-nonliteral๐ฎ.)-Wformat-signednessโ if-Wformatis on, also warn if the format string needs an unsigned argument but you pass a signed one, and vice versa ๐ง.-Wformat-truncation,-Wformat-truncation=levelโ warns about calls to formatted output functions likesnprintfandvsnprintfthat might result in output truncation โ๏ธ. The same heuristics apply: when the exact number of bytes isn't known at compile time, GCC estimates it based on thelevelargument and on optimization ๐. Optimization usually makes this more accurate, but it can also give false positives โญ. Except where noted otherwise, this option uses the same logic as-Wformat-overflow๐ .-Wformat-truncation,-Wformat-truncation=1โ level 1 is enabled by-Wformatand is conservative ๐ซถ. It only warns about calls to bounded functions whose return value is unused and that will most likely result in truncation ๐ฅบ.-Wformat-truncation=2โ level 2 also warns about calls to bounded functions whose return value is used, and that might truncate given an argument of sufficient length or magnitude ๐ฅ.
-Wformat-y2kโ if-Wformatis on, also warn aboutstrftimeformats that may only yield a two-digit year ๐ . Y2K is NOT the vibe ๐.-Wnonnullโ warns about passing a null pointer for arguments that thenonnullfunction attribute says must be non-null ๐ซ.-Wnonnullis included in-Walland-Wformat๐. You can turn it off with-Wno-nonnull๐ .-Wnonnull-compareโ warns when you compare an argument marked with thenonnullfunction attribute against null inside the function ๐. It's included in-Wallโจ, and you can disable it with-Wno-nonnull-compare๐ฆ.-Wnull-dereferenceโ the compiler gets suspicious here ๐ It warns when it finds code paths that lead to erroneous or undefined behaviour because a null pointer got dereferenced. This only kicks in while-fdelete-null-pointer-checksis active, and optimizations switch that on for most targets ๐ฅ How precise the warnings are depends on which optimization options you're using โจ-Winit-self(C, C++, Objective-C and Objective-C++ only) โ warns about uninitialized variables that get initialized with themselves ๐ Heads up, this one only works together with-Wuninitialized๐
GCC only warns about i being uninitialized in this snippet when -Winit-self is on:
int f()
{
int i = i;
return i;
}
And it's enabled by -Wall in C++ ๐ธ
-Wno-implicit-int(C and Objective-C only) โ controls the warnings for when a declaration doesn't specify a type ๐ง It's on by default in C99 and later dialects of C, and-Wallturns it on too ๐-Wno-implicit-function-declaration(C and Objective-C only) โ controls the warnings for when a function gets used before it's declared ๐ It's on by default in C99 and later dialects of C, and-Wallenables it as well. Heads up:-pedantic-errorsturns this one into a full error ๐ญ-Wimplicit(C and Objective-C only) โ same as-Wimplicit-intand-Wimplicit-function-declarationput together ๐ซถ Enabled by-Wall.-Wimplicit-fallthroughโ-Wimplicit-fallthroughis the same as-Wimplicit-fallthrough=3, and-Wno-implicit-fallthroughis the same as-Wimplicit-fallthrough=0๐ฆ-Wimplicit-fallthrough=nโ this one warns when a switch case falls through ๐ญ Like this:
switch (cond)
{
case 1:
a = 1;
break;
case 2:
a = 2;
case 3:
a = 3;
break;
}
It doesn't warn when the last statement of a case can't fall through, like a return or a call to a function declared with the noreturn attribute ๐ It also understands control flow statements like if, so it only warns when it actually makes sense ๐ง For example:
switch (cond)
{
case 1:
if (i > 3) {
bar (5);
break;
} else if (i < 1) {
bar (0);
} else
return;
default:
...
}
Sometimes a fallthrough is exactly what you want, so GCC gives you an attribute, __attribute__ ((fallthrough)), to use with a null statement. That suppresses the warning that would otherwise pop up ๐
switch (cond)
{
case 1:
bar (0);
__attribute__ ((fallthrough));
default:
...
}
C++17 has a standard way to silence -Wimplicit-fallthrough using [[fallthrough]]; instead of the GNU attribute. In C++11 or C++14, you can use [[gnu::fallthrough]];, which is a GNU extension โจ You can also add a fallthrough comment instead of any of these attributes to silence the warning. The whole body of the C or C++ style comment has to match the regular expressions listed below. The option argument n decides what kinds of comments count:
-Wimplicit-fallthrough=0disables the warning altogether ๐-Wimplicit-fallthrough=1matches the".*"regular expression, so any comment counts as a fallthrough comment.-Wimplicit-fallthrough=2case insensitively matches the".*falls?[ \t-]*thr(ough|u).*"regular expression.-Wimplicit-fallthrough=3case sensitively matches one of the following regular expressions:"-fallthrough""@fallthrough@""lint -fallthrough[ \t]*""[ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?""[ \t.!]*(Else,? |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?""[ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?"
-Wimplicit-fallthrough=4case sensitively matches one of the following regular expressions:"-fallthrough""@fallthrough@""lint -fallthrough[ \t]*""[ \t]*FALLTHR(OUGH|U)[ \t]*"
-Wimplicit-fallthrough=5doesn't recognize any comments as fallthrough comments, so only attributes disable the warning.
The comment needs to come right after optional whitespace and other comments, followed by a case or default keyword, or by a user label that sits in front of some case or default label ๐ซง Like so:
switch (cond)
{
case 1:
bar (0);
/* FALLTHRU */
default:
...
}
The -Wimplicit-fallthrough=3 warning is enabled by -Wextra ๐
-Wno-if-not-aligned(C, C++, Objective-C and Objective-C++ only) โ controls whether warnings triggered by thewarn_if_not_alignedattribute get issued ๐ These are enabled by default.-Wignored-qualifiers(C and C++ only) โ warns if a function's return type has a type qualifier likeconst๐ In ISO C, that qualifier does nothing, because a function's returned value isn't an lvalue. In C++, the warning only shows up for scalar types orvoid. ISO C doesn't allow qualifiedvoidreturn types on function definitions, so those always get a warning, even without this option ๐ This warning is also enabled by-Wextra.-Wno-ignored-attributes(C and C++ only) โ controls warnings for when an attribute gets ignored ๐ฆ It's different from-Wattributes: this one warns whenever the compiler decides to drop an attribute, not when the attribute is unknown, used in the wrong place, and so on. It's enabled by default.-Wmainโ warns if the type ofmainlooks sus ๐mainshould be a function with external linkage, returningint, and taking either zero arguments, two, or three arguments of appropriate types. It's enabled by default in C++, and by either-Wallor-Wpedantic.-Wmisleading-indentation(C and C++ only) โ warns when the indentation doesn't match the block structure ๐ซฃ Specifically, it warns forif,else,while, andforclauses with a guarded statement that has no braces, followed by an unguarded statement with the same indentation. Like here, the call tobaris indented as if theifguards it, but it isn't:
if (some_condition ())
foo ();
bar (); /* Gotcha: this is not guarded by the "if". */
If you mix tabs and spaces, the warning uses -ftabstop= to figure out whether statements line up. It defaults to 8 ๐
It isn't issued for code involving multiline preprocessor logic, like this:
if (flagA)
foo (0);
#if SOME_CONDITION_THAT_DOES_NOT_HOLD
if (flagB)
#endif
foo (1);
It also isn't issued after a #line directive, since that usually means autogenerated code, and no assumptions can be made about the layout of the file that the directive references ๐ This warning is enabled by -Wall in C and C++.
-Wmissing-attributesโ warns when a function declaration is missing one or more attributes that a related function is declared with, where the absence could hurt the correctness or efficiency of the generated code ๐ง For example, it fires for alias declarations that use attributes to set less restrictive requirements than their targets. That's usually a potential optimization opportunity โจ By contrast,-Wattribute-alias=2controls the warnings for when the alias is more restrictive than the target, which could lead to incorrect code generation ๐ Attributes considered include"alloc_align","alloc_size","cold","const","hot","leaf","malloc","nonnull","noreturn","nothrow","pure","returns_nonnull", and"returns_twice".
In C++, the warning is issued when an explicit specialization of a primary template is declared without one of these attributes that the primary template was declared with: "alloc_align", "alloc_size", "assume_aligned", "format", "format_arg", "malloc", or "nonnull". The attributes "deprecated", "error", and "warning" suppress the warning.
You can use the "copy" attribute to apply the same set of attributes to a declaration as another declaration has, without listing them all out. It can be applied to declarations of functions, variables, or types ๐ซถ
-Wmissing-attributes is enabled by -Wall ๐
Since the primary function template below uses both the "malloc" and "alloc_size" attributes, the explicit specialization of that template gets diagnosed for missing one of them ๐
template <class T>
T* __attribute__ ((malloc, alloc_size (1)))
allocate (size_t);
template <>
void* __attribute__ ((malloc)) // missing alloc_size
allocate<void> (size_t);
-Wmissing-bracesโ warns if an aggregate or union initializer isn't fully bracketed ๐ In the example below, the initializer foraisn't fully bracketed, but the one forbis:
int a[2][2] = { 0, 1, 2, 3 };
int b[2][2] = { { 0, 1 }, { 2, 3 } };
This warning is enabled by -Wall.
-Wmissing-include-dirs(C, C++, Objective-C and Objective-C++ only) โ warns if a user-supplied include directory doesn't exist ๐ธ
-Wno-missing-profile ๐
okay so this one is about the profile feedback warnings when you use -fprofile-use ๐ฅ. It basically catches the cases where you added a new function or a new file between -fprofile-generate and -fprofile-use and didn't regenerate your profiles. The profile feedback data files don't have any info for that new function or file, so it's giving missing data ๐ญ. Same deal if the profile count data (.gcda) files got deleted, because then GCC can't use any profile feedback at all. In all of these cases you get a warning telling you it's time for a profile generation step, and ignoring it can leave you with poorly optimized code ๐. -Wno-missing-profile turns the warning off, but tbh that's not recommended. Only use it when having no profile data is actually justified ๐.
-Wmultistatement-macros ๐
this one is for unsafe macros that have multiple statements and look like they're guarded by an if, else, for, switch, or while. The catch is that after expansion, only the first statement is actually guarded. Like, the bug is so sneaky ๐ญ:
#define DOIT x++; y++
if (c)
DOIT;
see how y gets incremented unconditionally, not just when c holds? That's the moment this warning saves your life โจ. This can usually be fixed by wrapping the macro in a do-while loop:
#define DOIT do { x++; y++; } while (0)
if (c)
DOIT;
This warning is enabled by -Wall in C and C++ ๐
.
-Wparentheses ๐ฆ
this warns when you skip parentheses in spots where people usually get confused. Think an assignment where a truth value is expected, or operators nested in a way that precedence trips everyone up ๐. It also warns if you write a comparison like x<=y<=z, which is equivalent to (x<=y ? 1 : 0) <= z. That is NOT what your math teacher meant, bestie ๐.
It also warns about dangerous uses of the GNU extension to ?: with the middle operand left out. When the condition is a boolean expression, the omitted value is always 1 ๐. Programmers often expect it to be a value computed inside the conditional expression instead, so this is a major vibe check ๐ฉ.
For C++, this also warns about some unnecessary parentheses in declarations, which can mean you were trying to make a function call instead of a declaration:
{
// Declares a local variable called mymutex.
std::unique_lock<std::mutex> (mymutex);
// User meant std::unique_lock<std::mutex> lock (mymutex);
}
This warning is enabled by -Wall โจ.
-Wsequence-point ๐
okay this one is a whole saga and I'm obsessed ๐ญ. It warns about code that may have undefined semantics because of violations of the sequence point rules in the C and C++ standards.
So sequence points are like little checkpoints in the evaluation order of your program: things executed before the checkpoint, and things executed after it ๐ง. They show up after a full expression is evaluated, after the first operand of &&, ||, ? :, or , (comma) is evaluated, before a function is called (but after its arguments and the expression naming the called function are evaluated), and in a few other places. Outside of those checkpoints, the order of evaluating subexpressions isn't specified at all ๐ธ. Even function calls within one expression, with no sequence point between them, can happen in any order. The standards committee did rule that function calls don't overlap, though ๐.
Here's the scary part. It's not specified when modifications to object values take effect between sequence points. Programs that depend on this have undefined behavior. The standards say:
"Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored."
If a program breaks these rules, the results on any particular implementation are entirely unpredictable ๐๐. Examples of undefined behavior include a = a++;, a[n] = b[n++], and a[i++] = i;. Some more complicated cases won't get flagged, and it might give an occasional false positive, but it's been found pretty effective at catching this kind of problem in real programs ๐ฅ.
The C++17 standard defines the order of evaluation in more cases. Specifically, the right-hand side of an assignment gets evaluated before the left-hand side, so the examples above aren't undefined anymore ๐ซถ. But this option will still warn about them anyway, to help people avoid writing code that's undefined in C and earlier revisions of C++ โจ.
The standard is worded confusingly, so there's some debate over the precise meaning of the sequence point rules in subtle cases ๐. Links to discussions of the problem, including proposed formal definitions, can be found on the GCC readings page at <http://gcc.gnu.org/readings.html> ๐.
This warning is enabled by -Wall for C and C++ ๐.
-Wno-return-local-addr ๐ท
this turns off the warning about returning a pointer (or a reference, in C++) to a variable that goes out of scope once the function returns. Use with caution, bestie, because that pointer is pointing at nothing ๐ฌ.
-Wreturn-type ๐
this one warns whenever a function is defined with a return type that defaults to int. It also warns about any return statement with no return value in a function whose return type isn't void. Falling off the end of the function body counts as returning without a value too, so no sneaking past it ๐.
For C only, it warns about a return statement with an expression in a function whose return type is void, unless the expression's type is also void. As a GNU extension, that last case is accepted without a warning unless -Wpedantic is used ๐
. Using the return value of a non-void function other than main that flows off the end by reaching the closing curly brace is undefined.
Unlike in C, in C++, flowing off the end of a non-voidfunction other thanmainresults in undefined behavior even when the value of the function is not used. Not a vibe ๐.
This warning is enabled by default in C++ and by -Wall otherwise โจ.
-Wno-shift-count-negative ๐ง
this controls warnings for a negative shift count. It's enabled by default, so you'd only use this option to turn it off ๐.
-Wno-shift-count-overflow ๐ฆ
this controls warnings if a shift count is greater than or equal to the bit width of the type. It's enabled by default too ๐.
-Wshift-negative-value ๐
this warns if you left shift a negative value. It's enabled by -Wextra in C99 (and newer) and in C++11 to C++17 modes โญ.
-Wno-shift-overflow, -Wshift-overflow=n ๐ฅ
these options control warnings about left shift overflows. There are two levels, and it's giving layers ๐ญ.
-Wshift-overflow=1โ this is the level you get from-Wshift-overflow, and it's enabled by default in C99 and C++11 modes (and newer) โจ. It doesn't warn about left-shifting 1 into the sign bit. (In C, though, that kind of overflow is still rejected in contexts where an integer constant expression is required.) There's no warning in C++2A mode (and newer), because signed left shifts always wrap now ๐ซถ.-Wshift-overflow=2โ this level also warns about left-shifting 1 into the sign bit, unless C++14 mode (or newer) is active ๐.
-Wswitch ๐
this warns whenever a switch statement has an index of enumerated type and is missing a case for one or more of the named codes in that enumeration. A default label prevents this warning, so you're covered if you have one ๐. case labels outside the enumeration range also trigger warnings with this option, even if there's a default label. It's enabled by -Wall โจ.
-Wswitch-default ๐ธ
this warns whenever a switch statement doesn't have a default case. Just a little reminder to be thorough ๐ซถ.
-Wswitch-enum ๐
this warns whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration. case labels outside the enumeration range also get warnings. The only difference between this and -Wswitch is that this one warns about an omitted enumeration code even when there's a default label ๐ฅ.
-Wno-switch-bool ๐
this turns off the warning for a switch statement whose index is boolean but whose case values are outside the range of a boolean type. If you want to shut it up without turning it off, cast the controlling expression to a type other than bool. For example:
switch ((int) (a == 4))
{
...
}
This warning is enabled by default for C and C++ programs ๐.
-Wno-switch-outside-range ๐ง
this controls warnings when a switch case has a value that's outside its respective type range. It's enabled by default for C and C++ programs โญ.
-Wno-switch-unreachable ๐
this turns off the warning about a switch statement that contains statements between the controlling expression and the first case label, which will never be executed. For example:
switch (cond)
{
i = 15;
...
case 5:
...
}
-Wswitch-unreachable doesn't warn if the statement between the controlling expression and the first case label is just a declaration:
switch (cond)
{
int i;
...
case 5:
i = 5;
...
}
This warning is enabled by default for C and C++ programs ๐.
-Wsync-nand (C and C++ only) ๐ฅ
this warns when the __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions get used. Heads up: these changed semantics in GCC 4.4, so old code might act different ๐.
-Wunused-but-set-parameter โจ
this warns whenever a function parameter gets assigned to but is otherwise unused (aside from its declaration). Assigned but never read? That's a main character who forgot their lines ๐ญ๐.
To suppress this warning, use the "unused" attribute. ๐ซถ
This warning is also enabled by -Wunused together with -Wextra. โจ
-Wunused-but-set-variableโ okay so this one yells when a local variable gets assigned to but never actually used (apart from its declaration) ๐ It's enabled by-Wall.
To suppress this warning, use the "unused" attribute. ๐ซถ
This warning is also enabled by -Wunused, which is enabled by -Wall. ๐
-Wunused-functionโ Warns whenever a static function is declared but not defined, or a non-inline static function is unused. ๐ฆ This warning is enabled by-Wall.-Wunused-labelโ Warns whenever a label is declared but never used. ๐ท๏ธ This warning is enabled by-Wall.
To suppress this warning, use the "unused" attribute. ๐ซถ
-Wunused-local-typedefs(C, Objective-C, C++ and Objective-C++ only) โ Warns when a typedef defined locally inside a function goes unused. ๐ง This warning is enabled by-Wall.-Wunused-parameterโ Warns whenever a function parameter is unused, aside from its declaration. ๐ธ
To suppress this warning, use the "unused" attribute. ๐ซถ
-Wno-unused-resultโ no drama here ๐ Stops the warning for when a caller of a function marked with the attribute"warn_unused_result"doesn't use its return value. The default is-Wunused-result.-Wunused-variableโ Warns whenever a local or static variable is unused, aside from its declaration. ๐ This option implies-Wunused-const-variable=1for C, but not for C++. This warning is enabled by-Wall.
To suppress this warning, use the "unused" attribute. ๐ซถ
-Wunused-const-variable,-Wunused-const-variable=nโ Warns whenever a constant static variable is unused, aside from its declaration. โจ-Wunused-const-variable=1gets turned on by-Wunused-variablefor C, but not for C++. In C this declares variable storage, but in C++ it's not an error, since const variables take the place of"#define"s. ๐คทโโ๏ธ
To suppress this warning, use the "unused" attribute. ๐ซถ
-Wunused-const-variable=1โ This is the warning level that-Wunused-variableturns on for C. ๐ It only warns about unused static const variables defined in the main compilation unit, and not about static const variables declared in any header that's included.-Wunused-const-variable=2โ This level also warns about unused constant static variables in headers (excluding system headers). ๐ง This is the warning level of-Wunused-const-variable, and you have to explicitly ask for it, since in C++ this isn't an error and in C it might be harder to clean up all the headers that get included.
-Wunused-valueโ Warns whenever a statement computes a result that's explicitly not used. ๐ To shush it, cast the unused expression to"void". This includes an expression-statement, or the left-hand side of a comma expression that has no side effects. For example, an expression such asx[i,j]causes a warning, whilex[(void)i,j]does not. ๐
This warning is enabled by -Wall.
-Wunusedโ all the above-Wunusedoptions, combined ๐
In order to get a warning about an unused function parameter, you must either specify -Wextra -Wunused (note that -Wall implies -Wunused), or separately specify -Wunused-parameter. ๐
-Wuninitializedโ Warns if an automatic variable is used before it's ever initialized. ๐ฅบ In C++, it also warns if a non-static reference or a non-static"const"member shows up in a class without constructors.
If you want to warn about code that uses the uninitialized value of the variable in its own initializer, use the -Winit-self option. ๐
These warnings happen for individual uninitialized elements of structure, union or array variables, as well as for variables that are uninitialized as a whole. They do not happen for variables or elements declared "volatile". Because these warnings depend on optimization, the exact variables or elements that get warnings depend on the precise optimization options and the version of GCC you're using. ๐
Note that there may be no warning about a variable that's only used to compute a value that's itself never used, because data flow analysis might delete those computations before the warnings are printed. ๐ซ
-Wno-invalid-memory-modelโ This option controls warnings for invocations of__atomicbuiltins,__syncbuiltins, and the C11 atomic generic functions, when they have a memory consistency argument that's either invalid for the operation or outside the range of values in thememory_orderenumeration. ๐ง For example, since__atomic_storeand__atomic_store_nare only defined for the relaxed, release, and sequentially consistent memory orders, the following code gets diagnosed:
void store (int *i)
{
__atomic_store_n (i, 0, memory_order_consume);
}
-Winvalid-memory-model is enabled by default. โ
-Wmaybe-uninitializedโ For an automatic (aka local) variable, if there's a path from the function entry to a use of the variable that's initialized, but some other paths leave it uninitialized, the compiler emits a warning if it can't prove the uninitialized paths never run at runtime. ๐ต๏ธโโ๏ธ
These warnings are only possible in optimizing compilation, because otherwise GCC doesn't keep track of the state of variables. ๐
These warnings are optional because GCC might not be able to tell when code is correct even though it looks like there's an error. Here's one example of how that happens:
{
int x;
switch (y)
{
case 1: x = 1;
break;
case 2: x = 4;
break;
case 3: x = 5;
}
foo (x);
}
If the value of y is always 1, 2 or 3, then x is always initialized, but GCC doesn't know that. To suppress the warning, you need to provide a default case with assert(0) or similar code. ๐ก๏ธ
Heads up, bestie ๐ญ This option also warns when a non-volatile automatic variable might be changed by a call to longjmp. The compiler only sees the calls to setjmp. It can't know where longjmp will be called; in fact, a signal handler could call it at any point in the code. As a result, you might get a warning even when there isn't really a problem, because longjmp can't actually be called at the place that would cause one.
Some spurious warnings can be avoided if you declare all the functions you use that never return as noreturn. ๐งน
This warning is enabled by -Wall or -Wextra. ๐ฅ
-Wunknown-pragmasโ Warns when a#pragmadirective shows up that GCC doesn't understand. ๐ฎ If this command-line option is used, warnings are even issued for unknown pragmas in system header files. That's not the case if the warnings are only enabled by the-Wallcommand-line option.-Wno-pragmasโ Doesn't warn about misuses of pragmas, like incorrect parameters, invalid syntax, or conflicts between pragmas. ๐ท See also-Wunknown-pragmas.-Wno-prio-ctor-dtorโ Doesn't warn if a priority from 0 to 100 is used for a constructor or destructor. ๐๏ธ The constructor and destructor attributes let you assign a priority to control their order of execution beforemainis called or after it returns. The priority values must be greater than 100, since the compiler reserves priority values0--100for itself. ๐ซ-Wstrict-aliasingโ This option is only active when-fstrict-aliasingis active. ๐ฏ It warns about code that might break the strict aliasing rules the compiler uses for optimization. It doesn't catch every case, but it does try to catch the more common pitfalls. It's included in-Wall. It's equivalent to-Wstrict-aliasing=3.-Wstrict-aliasing=nโ Also only active when-fstrict-aliasingis active. ๐ง It warns about code that might break the strict aliasing rules the compiler uses for optimization. Higher levels mean higher accuracy (fewer false positives). Higher levels also take more effort, kind of like how-Oworks.-Wstrict-aliasingis equivalent to-Wstrict-aliasing=3.- Level 1 โ Most aggressive, quick, and least accurate. ๐ฃ It's possibly useful when higher levels don't warn but
-fstrict-aliasingstill breaks the code, since it has very few false negatives. However, it has many false positives. It warns for all pointer conversions between possibly incompatible types, even if the pointer is never dereferenced. It runs in the front end only. - Level 2 โ Aggressive, quick, and not too precise. ๐ It may still have many false positives (not as many as level 1, though), and few false negatives (but possibly more than level 1). Unlike level 1, it only warns when an address is taken. It warns about incomplete types. It runs in the front end only.
- Level 3 (default for
-Wstrict-aliasing) โ Should have very few false positives and few false negatives. ๐ It's slightly slower than levels 1 or 2 when optimization is enabled. It takes care of the common pun+dereference pattern in the front end:*(int*)&some_float. If optimization is enabled, it also runs in the back end, where it deals with multiple-statement cases using flow-sensitive points-to information. It only warns when the converted pointer is dereferenced. It does not warn about incomplete types.
- Level 1 โ Most aggressive, quick, and least accurate. ๐ฃ It's possibly useful when higher levels don't warn but
-Wstrict-overflow,-Wstrict-overflow=nโ This option is only active when signed overflow is undefined. ๐ It warns about cases where the compiler optimizes based on the assumption that signed overflow doesn't happen. It doesn't warn about every case where the code might overflow: it only warns about cases where the compiler actually implements some optimization. So this warning depends on the optimization level. ๐ค
Okay so, assuming signed overflow never happens is totally safe as long as the numbers in your code never actually overflow ๐ . That means this warning can give a false positive, which is a warning about code that isn't actually a problem ๐. To help you focus on what matters, GCC has several warning levels โจ. No warnings get issued for undefined signed overflow when the compiler is estimating how many iterations a loop needs, especially when it's figuring out whether a loop runs at all ๐.
-Wstrict-overflow=1โ Warns about stuff that's both questionable and easy to avoid ๐. For example, the compiler turnsx + 1 > xinto1. This level is turned on by-Wall, but the higher levels aren't, so you have to ask for them yourself ๐.-Wstrict-overflow=2โ Also warns about other spots where a comparison gets simplified to a constant, likeabs (x) >= 0๐. This one only works because signed integer overflow is undefined, sinceabs (INT_MIN)overflows toINT_MIN, which is less than zero. Also,-Wstrict-overflowwith no level is the same as-Wstrict-overflow=2๐ฆ.-Wstrict-overflow=3โ Also warns about other comparisons that get simplified, likex + 1 > 1becomingx > 0๐ธ.-Wstrict-overflow=4โ Also warns about other simplifications that aren't covered above, like(x * 10) / 5becomingx * 2โจ.-Wstrict-overflow=5โ Also warns when the compiler reduces the magnitude of a constant in a comparison, likex + 2 > ybecomingx + 1 >= y. This only gets reported at the highest level because this simplification applies to so many comparisons that it gives a very large number of false positives ๐ญ.
-Wstring-compare
Warns for calls to strcmp and strncmp whose result is determined to be either zero or non-zero in equality tests, because the length of one argument is bigger than the size of the array the other argument is stored in (or the bound, for strncmp). These calls could be mistakes ๐ค. For example, the strcmp call below gets diagnosed because its result is necessarily non-zero no matter what's in the array a.
extern char a[4];
void f (char *d)
{
strcpy (d, "string");
...
if (0 == strcmp (a, d)) // cannot be true
puts ("a and d are the same");
}
-Wstring-compare is enabled by -Wextra ๐.
-Wstringop-overflow, -Wstringop-overflow=type
Warns for calls to string manipulation functions like memcpy and strcpy that are determined to overflow the destination buffer ๐จ. The optional argument is one greater than the type of Object Size Checking to perform to determine the size of the destination. This argument only matters for functions that work on character arrays, not raw memory functions like memcpy, which always use Object Size type-0. The option also warns for calls that specify a size bigger than the largest possible object, or at most SIZE_MAX / 2 bytes ๐งฎ. It gives the best results with optimization turned on, but it can catch a small subset of simple buffer overflows even without optimization, in calls to GCC built-ins like __builtin_memcpy that match the standard functions. Either way, it only warns about a subset of the buffer overflows that the matching overflow checking built-ins catch ๐ซถ. For example, this option warns for the strcpy call below, because it copies at least 5 characters (the string "blue" including the terminating NUL) into a buffer of size 4.
enum Color { blue, purple, yellow };
const char* f (enum Color clr)
{
static char buf [4];
const char *str;
switch (clr)
{
case blue: str = "blue"; break;
case purple: str = "purple"; break;
case yellow: str = "yellow"; break;
}
return strcpy (buf, str); // warning here
}
Heads up: -Wstringop-overflow=2 is enabled by default ๐.
-Wstringop-overflow, -Wstringop-overflow=1
This one uses type-zero Object Size Checking to figure out the sizes of destination objects ๐ง. It's the default setting of the option. At this setting, it doesn't warn for writes past the end of subobjects of larger objects accessed through pointers, unless the size of the largest surrounding object is known. When the destination might be one of several objects, it's assumed to be the largest one of them. On Linux systems, when optimization is enabled at this setting, the option warns for the same code that gets warned about when the _FORTIFY_SOURCE macro is defined to a non-zero value ๐ง.
-Wstringop-overflow=2
This uses type-one Object Size Checking for destination sizes ๐. At this setting, the option warns about overflows when writing to members of the largest complete objects whose exact size is known. It does not warn for excessive writes to the same members of unknown objects referenced by pointers, since those pointers might point to arrays with an unknown number of elements ๐คทโโ๏ธ.
-Wstringop-overflow=3
This uses type-two Object Size Checking ๐. At this setting, the option warns about overflowing the smallest object or data member. It's the most restrictive setting that can still warn for safe code ๐ฌ.
-Wstringop-overflow=4
This uses type-three Object Size Checking ๐งฉ. At this setting, the option warns about overflowing any data members. When the destination is one of several objects, it uses the size of the largest of them to decide whether to warn. Just like -Wstringop-overflow=3, this setting may result in warnings for benign code ๐.
-Wno-stringop-truncation
Do not warn for calls to bounded string manipulation functions like strncat, strncpy, and stpncpy that might either truncate the copied string or leave the destination unchanged ๐
โโ๏ธ.
In the following example, the call to strncat specifies a bound that's less than the length of the source string. So the copy gets truncated, and the call is diagnosed. To avoid the warning, use bufsize - strlen (buf) - 1) as the bound ๐
.
void append (char *buf, size_t bufsize)
{
strncat (buf, ".txt", 3);
}
Here's another one. The following call to strncpy copies only the characters before the terminating NUL into d, without appending the NUL to the end. Assuming the result of strncpy is always a NUL-terminated string is a super common mistake, so this call gets diagnosed ๐ญ. To avoid the warning when the result isn't expected to be NUL-terminated, call memcpy instead ๐.
void copy (char *d, const char *s)
{
strncpy (d, s, strlen (s));
}
In this example, the call to strncpy uses the size of the destination buffer as the bound. If the length of the source string is equal to or greater than that size, the result won't be NUL-terminated, so the call is also diagnosed โ ๏ธ. To avoid the warning, specify sizeof buf - 1 as the bound and set the last element of the buffer to NUL.
void copy (const char *s)
{
char buf[80];
strncpy (buf, s, sizeof buf);
...
}
Heads up: if a character array is meant to store a sequence of bytes with no terminating NUL, you can annotate it with the attribute nonstring to avoid this warning ๐. But these arrays aren't suitable arguments for functions that expect NUL-terminated strings. To help catch accidental misuse of them, GCC issues warnings unless it can prove the use is safe ๐ก๏ธ.
-Wsuggest-attribute=pure, -Wsuggest-attribute=const, -Wsuggest-attribute=noreturn, -Wmissing-noreturn, -Wsuggest-attribute=malloc
Warns about functions that might be candidates for the attributes pure, const, noreturn, or malloc ๐ช. The compiler only warns for functions that are visible in other compilation units, or (for pure and const) if it can't prove that the function returns normally. A function returns normally if it doesn't contain an infinite loop and doesn't return abnormally by throwing, calling abort, or trapping โพ๏ธ. This analysis needs the option -fipa-pure-const, which is enabled by default at -O and higher. Higher optimization levels make the analysis more accurate ๐.
-Wsuggest-attribute=format, -Wmissing-format-attribute
Warns about function pointers that might be candidates for format attributes ๐ซ. These are only possible candidates, not absolute ones. GCC guesses that function pointers with format attributes that get used in assignment, initialization, parameter passing, or return statements should also have a matching format attribute in the resulting type ๐ง . That means the left-hand side of the assignment or initialization, the type of the parameter variable, or the return type of the containing function, respectively, should also have a format attribute to avoid the warning ๐ธ.
GCC also yells about function definitions that might be candidates for format attributes ๐. Again, these are only possible candidates, not sure things ๐ซถ. GCC guesses a format attribute might fit any function that calls something like vprintf or vscanf, but that's not always true ๐
, and some functions that really do need format attributes might slip past the detection ๐.
-Wsuggest-attribute=coldโ warns about functions that might be candidates for thecoldattribute โ๏ธ. This is based on static detection and generally only fires for functions that always lead to a call to anothercoldfunction, like wrappers around C++throwor fatal error reporting functions that lead toabort.
-Walloc-zeroโ warns about calls to allocation functions decorated with thealloc_sizeattribute that ask for zero bytes ๐ซ . That includes the built-in forms ofaligned_alloc,alloca,calloc,malloc, andrealloc. The behavior at zero size differs between implementations (andreallochas been deprecated for it), so relying on it can cause sneaky portability bugs and should be avoided.-Walloc-size-larger-than=byte-sizeโ warns about calls to functions decorated with thealloc_sizeattribute that try to allocate objects bigger than the number of bytes you specify ๐. It also warns when the size computation, done in an integer type with infinite precision, would go pastPTRDIFF_MAXon the target.-Walloc-size-larger-than=PTRDIFF_MAXis enabled by default. You can turn these warnings off by giving a byte-size ofSIZE_MAXor more, or by using-Wno-alloc-size-larger-than.-Wno-alloc-size-larger-thanโ disables-Walloc-size-larger-than=warnings. It's the same as-Walloc-size-larger-than=SIZE_MAXor larger ๐ธ.-Wallocaโ warns on all uses ofallocain the source ๐จ.-Walloca-larger-than=byte-sizeโ warns on calls toallocawhose integer argument is either zero, or isn't bounded by a controlling predicate that limits it to at most byte-size ๐ง. It also warns for calls toallocawhere the bound is unknown. Arguments of non-integer types count as unbounded, even if they look like they're in the expected range.
A bounded case of alloca could look like this:
void func (size_t n)
{
void *p;
if (n <= 1000)
p = alloca (n);
else
p = malloc (n);
f (p);
}
In the example above, passing -Walloca-larger-than=1000 would not warn, because the call to alloca is known to be at most 1000 bytes โ
. But if -Walloca-larger-than=500 were passed, the compiler would emit a warning โ ๏ธ.
Unbounded uses are the opposite: alloca calls with no controlling predicate constraining their integer argument ๐ฌ. For example:
void func ()
{
void *p = alloca (n);
f (p);
}
If -Walloca-larger-than=500 were passed, the above would trigger a warning, this time because there's no bounds checking at all ๐.
Note that even seemingly correct code using signed integers can cause a warning:
void func (signed int n)
{
if (n < 500)
{
p = alloca (n);
f (p);
}
}
In that example, n could be negative, which would cause a larger-than-expected argument to be implicitly cast into the alloca call ๐ซฃ.
This option also warns when alloca is used in a loop ๐.
-Walloca-larger-than=PTRDIFF_MAX is enabled by default, but it's usually only effective when -ftree-vrp is active (which is the default for -O2 and above) ๐.
See also -Wvla-larger-than=byte-size.
-Wno-alloca-larger-thanโ disables-Walloca-larger-than=warnings. It's equivalent to-Walloca-larger-than=SIZE_MAXor larger ๐ .-Warith-conversionโ warns about implicit conversions coming from arithmetic operations, even when converting the operands to the same type can't change their values ๐งฎ. This affects warnings from-Wconversion,-Wfloat-conversion, and-Wsign-conversion.
void f (char c, int i)
{
c = c + i; // warns with -Wconversion
c = c + 1; // only warns with -Warith-conversion
}
-Warray-bounds,-Warray-bounds=nโ this option is only active when-ftree-vrpis active (the default for-O2and above) ๐. It warns about subscripts to arrays that are always out of bounds ๐ . This warning is enabled by-Wall.-Warray-bounds=1โ this is the warning level of-Warray-boundsand it's enabled by-Wallโจ. Higher levels aren't enabled by-Wall, so you have to ask for them explicitly.-Warray-bounds=2โ this level also warns about out-of-bounds access for arrays at the end of a struct, and for arrays accessed through pointers ๐. It may give a bigger pile of false positives, so it's deactivated by default ๐.
-Wattribute-alias=n,-Wno-attribute-aliasโ warns about declarations using thealiasand similar attributes whose target is incompatible with the type of the alias ๐ฆ.-Wattribute-alias=1โ this is the default warning level, and it diagnoses incompatibilities between the type of the alias declaration and the type of its target. Those incompatibilities are usually a sign of bugs ๐.-Wattribute-alias=2โ at this level,-Wattribute-aliasalso diagnoses cases where the alias declaration's attributes are more restrictive than the attributes on its target ๐ง. These mismatches can lead to incorrect code generation โ ๏ธ. In other cases they might be harmless, and could be fixed just by adding the missing attribute to the target. For comparison, see-Wmissing-attributes, which covers the opposite situation, where the alias declaration is less restrictive than the target.
The attributes considered include "alloc_align", "alloc_size", "cold", "const", "hot", "leaf", "malloc", "nonnull", "noreturn", "nothrow", "pure", "returns_nonnull", and "returns_twice" ๐.
-Wattribute-alias is equivalent to -Wattribute-alias=1, and that's the default ๐. You can disable these warnings with either -Wno-attribute-alias or -Wattribute-alias=0.
-Wbool-compareโ warns about a boolean expression compared with an integer value other thantrueorfalse๐ค. For instance, this comparison is always false:
int n = 5;
...
if ((n > 1) == 2) { ... }
This warning is enabled by -Wall.
-Wbool-operationโ warns about suspicious operations on expressions of a boolean type ๐ซข. For instance, bitwise negation of a boolean is very likely a bug in the program. For C, this warning also covers incrementing or decrementing a boolean, which rarely makes sense.
In C++, decrementing a boolean is always invalid. Incrementing a boolean is invalid in C++17, and deprecated otherwise.
This warning is enabled by -Wall.
-Wduplicated-branchesโ warns when anif-elsehas identical branches ๐ฏ. This warning catches cases like:
if (p != NULL)
return 0;
else
return 0;
It doesn't warn when both branches contain just a null statement. This warning also covers conditional operators:
int i = x ? *p : *p;
-Wduplicated-condโ warns about duplicated conditions in anif-else-ifchain ๐. For instance, it warns on this code:
if (p->q != NULL) { ... }
else if (p->q != NULL) { ... }
-Wframe-addressโ warns when__builtin_frame_addressor__builtin_return_addressis called with an argument greater than0๐ . Such calls may return indeterminate values or crash the program ๐ฅ. This warning is included in-Wall.-Wno-discarded-qualifiers(C and Objective-C only) โ stops the warning about type qualifiers on pointers being discarded ๐. Typically the compiler warns if aconst char *variable is passed to a function that takes achar *parameter. Use this option to suppress that warning ๐ซถ.-Wno-discarded-array-qualifiers(C and Objective-C only) โ stops the warning about type qualifiers on arrays that are pointer targets being discarded ๐. Typically the compiler warns if aconst int (*)[]variable is passed to a function that takes anint (*)[]parameter. Use this option to suppress that warning.-Wno-incompatible-pointer-types(C and Objective-C only) โ stops the warning when there's a conversion between pointers with incompatible types ๐งท. This covers cases not handled by-Wno-pointer-sign, which warns about pointer argument passing or assignment with different signedness.-Wno-int-conversion(C and Objective-C only) โ stops the warnings about incompatible integer-to-pointer and pointer-to-integer conversions ๐ข. This warning is about implicit conversions. For explicit conversions, you can use-Wno-int-to-pointer-castand-Wno-pointer-to-int-castinstead.-Wzero-length-boundsโ warns about accesses to elements of zero-length array members that might overlap other members of the same object ๐. Declaring interior zero-length arrays is discouraged, because accesses to them are undefined.
Accesses to interior zero-length arrays are undefined, so please don't go poking around in them. See
For example, the first two stores in the function bad are diagnosed, because those array elements overlap the subsequent members b and c ๐ญ. The third store is diagnosed by -Warray-bounds, because it's beyond the bounds of the enclosing object.
struct X { int a[0]; int b, c; };
struct X x;
void bad (void)
{
x.a[0] = 0; // -Wzero-length-bounds
x.a[1] = 1; // -Wzero-length-bounds
x.a[2] = 2; // -Warray-bounds
}
Option -Wzero-length-bounds is enabled by -Warray-bounds ๐.
-Wno-div-by-zeroโ okay so this one turns off the warning for compile-time integer division by zero ๐ Floating-point division by zero doesn't get warned about either, bc it can be a legit way to get infinities and NaNs โจ-Wsystem-headersโ prints warnings for constructs found in system header files ๐ Those get hushed by default bc they usually aren't real problems and would just make the output harder to read. This flag tells GCC to treat system header warnings like they came from your own code ๐ซถ Heads up tho: using-Wallwith this doesn't warn about unknown pragmas in system headers---for that, you ALSO need-Wunknown-pragmas๐-Wtautological-compareโ warns if a self-comparison always evaluates to true or false ๐ It catches mistakes like this:
int i = 1;
...
if (i > i) { ... }
It also warns about bitwise comparisons that always come out true or false, like this one, which is always false, no cap ๐
if ((a & 16) == 10) { ... }
This warning is enabled by -Wall.
-Wtrampolinesโ warns about trampolines generated for pointers to nested functions ๐ฆ A trampoline is a little piece of data or code that gets created at run time on the stack when the address of a nested function is taken, and it's used to call that nested function indirectly. Some targets only use data, so they need no special treatment. But most targets use code, which means the stack has to be made executable for the program to work properly.-Wfloat-equalโ warns if floating-point values are used in equality comparisons ๐ธ The idea is that sometimes it's convenient to treat floats as approximations of infinitely precise real numbers. If you're doing that, you need to figure out the maximum (or likely maximum) error the computation introduces, and allow for it when comparing (and when producing output, but that's a different problem). So instead of testing for equality, check whether the two values have ranges that overlap. That's done with the relational operators, so equality comparisons are probably a mistake ๐ญ-Wtraditional(C and Objective-C only) โ warns about constructs that behave differently in traditional C and ISO C ๐ง It also warns about ISO C constructs with no traditional C equivalent, and problematic constructs you should avoid. Here's the lineup:- Macro parameters that show up inside string literals in the macro body. Traditional C does macro replacement inside string literals, but ISO C doesn't.
- Some preprocessor directives didn't exist in traditional C. Traditional preprocessors only considered a line a directive if the
#was in column 1. So-Wtraditionalwarns about directives that traditional C understands but ignores because the#isn't the first character on the line. It also suggests hiding directives like#pragmathat traditional C doesn't understand by indenting them. Some traditional implementations don't recognize#elif, so this option suggests avoiding it altogether. - A function-like macro that shows up without arguments.
- The unary plus operator.
- The
Uinteger constant suffix, or theForLfloating-point constant suffixes. (Traditional C does support theLsuffix on integer constants.) These suffixes appear in macros defined in the system headers of most modern systems, e.g. the_MIN/_MAXmacros in<limits.h>. Using those macros in user code might normally lead to spurious warnings, but GCC's integrated preprocessor has enough context to avoid warning in these cases. - A function declared external in one block and then used after the end of that block.
- A
switchstatement with an operand of typelong. - A non-
staticfunction declaration that follows astaticone. Some traditional C compilers don't accept this. - The ISO type of an integer constant has a different width or signedness from its traditional type. This warning is only issued if the base of the constant is ten. Hexadecimal or octal values, which typically represent bit patterns, aren't warned about.
- Usage of ISO string concatenation is detected.
- Initialization of automatic aggregates.
- Identifier conflicts with labels. Traditional C lacks a separate namespace for labels.
- Initialization of unions. If the initializer is zero, the warning is omitted. This is done under the assumption that a zero initializer in user code appears conditioned on something like
__STDC__to avoid missing-initializer warnings, and relies on default initialization to zero in the traditional C case. - Conversions by prototypes between fixed-point and floating-point values, and vice versa. The absence of these prototypes when compiling with traditional C causes serious problems. This is a subset of the possible conversion warnings; for the full set, use
-Wtraditional-conversion. - Use of ISO C style function definitions. This warning intentionally isn't issued for prototype declarations or variadic functions, because those ISO C features show up in your code when using libiberty's traditional C compatibility macros,
PARAMSandVPARAMS. The warning is also bypassed for nested functions, because that feature is already a GCC extension and thus not relevant to traditional C compatibility.
-Wtraditional-conversion(C and Objective-C only) โ warns if a prototype causes a type conversion that's different from what would happen to the same argument without a prototype ๐ฅ This includes conversions of fixed point to floating and vice versa, and conversions that change the width or signedness of a fixed-point argument, except when that matches the default promotion.-Wdeclaration-after-statement(C and Objective-C only) โ warns when a declaration is found after a statement in a block ๐ This construct is borrowed from C++, was introduced with ISO C99, and is allowed by default in GCC. It is not supported by ISO C90.-Wshadowโ warns whenever a local variable or type declaration shadows another variable, parameter, type, class member (in C++), or instance variable (in Objective-C), or whenever a built-in function gets shadowed ๐ In C++, the compiler warns if a local variable shadows an explicit typedef, but not if it shadows a struct, class, or enum. If this warning is enabled, it also includes all instances of local shadowing. That means-Wno-shadow=localand-Wno-shadow=compatible-localare ignored when-Wshadowis used. Same as-Wshadow=global.-Wno-shadow-ivar(Objective-C only) โ don't warn when a local variable shadows an instance variable in an Objective-C method ๐ โโ๏ธ-Wshadow=globalโ warns for any shadowing. Same as-Wshadow.-Wshadow=localโ warns when a local variable shadows another local variable or parameter.-Wshadow=compatible-localโ warns when a local variable shadows another local variable or parameter whose type is compatible with the type of the shadowing variable. In C++, type compatibility here means the type of the shadowing variable can be converted to that of the shadowed variable. This flag exists bc the idea is that when a local variable shadows another one of incompatible type, it's most likely intentional and not a bug or typo, like in this example โจ
for (SomeIterator i = SomeObj.begin(); i != SomeObj.end(); ++i)
{
for (int i = 0; i < N; ++i)
{
...
}
...
}
Since the two variable i in the example above have incompatible types, enabling only -Wshadow=compatible-local does not emit a warning. Bc their types are incompatible, if a programmer accidentally uses one in place of the other, type checking is expected to catch that and emit an error or warning. Using this flag instead of -Wshadow=local can possibly reduce the number of warnings triggered by intentional shadowing. Note that this also means shadowing const char *i by char *i does not emit a warning.
This warning is also enabled by -Wshadow=local.
-Wlarger-than=byte-sizeโ warns whenever an object is defined whose size exceeds byte-size ๐-Wlarger-than=PTRDIFF_MAXis enabled by default. Warnings controlled by this option can be disabled either by specifying a byte-size ofSIZE_MAXor more, or by-Wno-larger-than.-Wno-larger-thanโ disables-Wlarger-than=warnings. The option is equivalent to-Wlarger-than=SIZE_MAXor larger.-Wframe-larger-than=byte-sizeโ warns if the size of a function frame exceeds byte-size ๐งฑ The computation used to determine the stack frame size is approximate and not conservative, so the actual requirements may be somewhat greater than byte-size even if you don't get a warning. Also, any space allocated viaalloca, variable-length arrays, or related constructs is not included by the compiler when deciding whether to warn.-Wframe-larger-than=PTRDIFF_MAXis enabled by default. Warnings controlled by this option can be disabled either by specifying a byte-size ofSIZE_MAXor more, or by-Wno-frame-larger-than.-Wno-frame-larger-thanโ disables-Wframe-larger-than=warnings. The option is equivalent to-Wframe-larger-than=SIZE_MAXor larger.-Wno-free-nonheap-objectโ don't warn when attempting to free an object that was not allocated on the heap ๐-Wstack-usage=byte-sizeโ okay so this one screams if a function's stack usage might go pastbyte-size๐ The math is on the cautious side ๐ง , and any room grabbed withalloca, variable-length arrays, or similar constructs gets counted too ๐ The messages match the vibe of-fstack-usageโจ- if the stack usage is fully static but goes over your limit, it's:
warning: stack usage is 1120 bytes - if it's (partly) dynamic but bounded, it's:
warning: stack usage might be 1648 bytes - if it's (partly) dynamic and not bounded, it's:
warning: stack usage might be unbounded - heads up ๐
-Wstack-usage=PTRDIFF_MAXis on by default. You can silence these by passing abyte-sizeofSIZE_MAXor more, or by using-Wno-stack-usage๐
- if the stack usage is fully static but goes over your limit, it's:
-Wno-stack-usageโ no more-Wstack-usage=warnings ๐ซถ This is the same as-Wstack-usage=SIZE_MAXor anything bigger-Wunsafe-loop-optimizationsโ this one warns when a loop can't be optimized because the compiler can't assume anything about the bounds of the loop indices ๐ With-funsafe-loop-optimizations, it warns when the compiler does make those assumptions ๐-Wno-pedantic-ms-format(MinGW targets only) โ when you're using-Wformatand-pedanticwithout GNU extensions, this turns off the warnings about non-ISOprintf/scanfwidth specifiersI32,I64, andI๐ช Those work on Windows targets because they depend on the MS runtime, so they're not technically ISO, but they're valid there ๐ธ-Wpointer-arithโ warns about anything that depends on the "size of" a function type or ofvoid๐งฎ GNU C gives these types a size of 1, which is handy when you're doing math withvoid *pointers and pointers to functions. In C++, it also warns when an arithmetic operation involvesNULL๐ โโ๏ธ This warning is also enabled by-Wpedantic-Wno-pointer-compareโ don't warn when a pointer gets compared with a zero character constant ๐ That usually means the pointer was supposed to be dereferenced. Here's the classic oops:
const char *p = foo ();
if (p == '\0')
return 42;
Note that the code above is invalid in C++11 ๐ This warning is enabled by default
-Wtype-limitsโ warns if a comparison is always true or always false because of the limited range of the data type, but it won't warn for constant expressions ๐ง For example, it'll flag an unsigned variable being compared against zero with<or>=. This one is also enabled by-Wextra๐ฅ-Wabsolute-value(C and Objective-C only) โ warns when you call a standard absolute-value function and there's a more appropriate standard function available ๐ซง For example, callingabs(3.14)triggers it, because the right function for a double isfabs. It also warns when the argument to such a function has an unsigned type. You can suppress it with an explicit type cast, and it's enabled by-Wextra๐-Wcomment,-Wcommentsโ warns whenever a comment-start sequence/*shows up inside a/*comment, or whenever a backslash-newline shows up in a//comment ๐ฌ This warning is enabled by-Wall-Wtrigraphsโ warns if any trigraphs are found that might change what the program means ๐ Trigraphs inside comments don't get warned about, except the ones that would form escaped newlines. This option is implied by-Wall. If-Wallisn't given, it's still enabled unless trigraphs are enabled. Want trigraph conversion without the warnings but still the other-Wallwarnings? Use-trigraphs -Wall -Wno-trigraphs๐-Wundefโ warns if an undefined identifier gets evaluated in an#ifdirective ๐งฉ Those identifiers get replaced with zero-Wexpansion-to-definedโ warns wheneverdefinedshows up in the expansion of a macro, including when the macro gets expanded by an#ifdirective ๐ซ That usage isn't portable. This warning is also enabled by-Wpedanticand-Wextra-Wunused-macrosโ warns about macros defined in the main file that never get used ๐๏ธ A macro counts as used if it's expanded or tested for existence at least once. The preprocessor also warns if the macro hasn't been used by the time it's redefined or undefined. Built-in macros, macros defined on the command line, and macros defined in include files are not warned about ๐ โโ๏ธ
Note: if a macro is used, but only inside skipped conditional blocks, the preprocessor still reports it as unused ๐ญ To dodge the warning, you could improve the scope of the macro's definition, like moving it into the first skipped block. Or you could add a dummy use, something like:
#if defined the_macro_causing_the_warning
#endif
-Wno-endif-labelsโ don't warn when an#elseor an#endifis followed by text ๐ This happens sometimes in older programs with code like this:
#if FOO
...
#else FOO
...
#endif FOO
The second and third FOO should be in comments. This warning is on by default ๐
-Wbad-function-cast(C and Objective-C only) โ warns when a function call gets cast to a non-matching type ๐ญ For example, it warns if a call to a function returning an integer type gets cast to a pointer type-Wc90-c99-compat(C and Objective-C only) โ warns about features that aren't in ISO C90 but are in ISO C99 ๐ Think variable length arrays, thelong longtype, thebooltype, compound literals, designated initializers, and so on. This option doesn't care about the standards mode. Warnings are turned off in the expression that follows__extension__-Wc99-c11-compat(C and Objective-C only) โ warns about features that aren't in ISO C99 but are in ISO C11 ๐ฆ That covers anonymous structures and unions, the_Atomictype qualifier, the_Thread_localstorage-class specifier, the_Alignasspecifier, theAlignofoperator, the_Generickeyword, and so on. Again, it's independent of the standards mode, and warnings are disabled in the expression that follows__extension__-Wc11-c2x-compat(C and Objective-C only) โ warns about features that aren't in ISO C11 but are in ISO C2X ๐ฎ For instance, it warns about omitting the string in_Static_assert, using[[]]attribute syntax, and using decimal floating-point types, plus more. Independent of the standards mode, and warnings are disabled in the expression that follows__extension__-Wc++-compat(C and Objective-C only) โ warns about ISO C constructs that sit outside the common subset of ISO C and ISO C++ ๐ง For example, asking for an implicit conversion fromvoid *to a pointer to non-voidtype-Wc++11-compat(C++ and Objective-C++ only) โ warns about C++ constructs whose meaning changes between ISO C++ 1998 and ISO C++ 2011 ๐งท For example, identifiers in ISO C++ 1998 that became keywords in ISO C++ 2011. This warning turns on-Wnarrowingand is enabled by-Wall-Wc++14-compat(C++ and Objective-C++ only) โ warns about C++ constructs whose meaning differs between ISO C++ 2011 and ISO C++ 2014 ๐ This warning is enabled by-Wall-Wc++17-compat(C++ and Objective-C++ only) โ warns about C++ constructs whose meaning differs between ISO C++ 2014 and ISO C++ 2017 โญ This warning is enabled by-Wall-Wc++20-compat(C++ and Objective-C++ only) โ warns about C++ constructs whose meaning differs between ISO C++ 2017 and ISO C++ 2020 ๐ This warning is enabled by-Wall
-Wcast-qualโ warns whenever a pointer gets cast in a way that removes a type qualifier from the target type ๐ซฃ For example, it warns if aconst char *gets cast to an ordinarychar *. It also warns when a cast adds a type qualifier in an unsafe way. Castingchar **toconst char **is unsafe, as you can see here:
/* p is char ** value. */
const char **q = (const char **) p;
/* Assignment of readonly string to const char * is OK. */
*q = "string";
/* Now char** pointer points to read-only memory. */
**p = 'b';
-Wcast-alignโ warns whenever a pointer gets cast so the required alignment of the target goes up ๐ For example, it warns if achar *gets cast to anint *on machines where integers can only be accessed at two- or four-byte boundaries-Wcast-align=strictโ same deal, but it warns whenever the required alignment goes up, regardless of the target machine ๐งฑ So achar *cast to anint *gets flagged no matter what-Wcast-function-typeโ warns when a function pointer gets cast to an incompatible function pointer ๐ช For casts involving function types with a variable argument list, only the types of the initial arguments that are actually provided get considered. Any pointer-type parameter matches any other pointer-type. Benign differences in integral types get ignored, likeintvs.longon ILP32 targets. Type qualifiers are ignored too. The function typevoid (*) (void)is special and matches everything, so you can use it to suppress this warning. For casts involving pointer to member types, the warning fires whenever the cast changes the pointer to member type. This warning is enabled by-Wextra๐ซถ-Wwrite-stringsโ when compiling C, this gives string constants the typeconst char[length], so copying the address of one into a non-constchar *pointer produces a warning ๐งต These warnings help you find code at compile time that might try to write into a string constant, but only if you've been super careful withconstin your declarations and prototypes. Otherwise, it's just a nuisance. That's why-Walldoesn't request these warnings. When compiling C++, it warns about the deprecated conversion from string literals tochar *. This warning is enabled by default for C++ programs ๐-Wclobberedโ warns about variables that might get changed bylongjmporvfork๐ This warning is also enabled by-Wextra-Wconversionโ okay, the implicit-conversion police are HERE ๐ฎโโ๏ธโจ It warns when an implicit conversion might alter a value, like real-to-integer stuff such asabs (x)whenxisdouble, signed-vs-unsigned chaos likeunsigned ui = -1, or squishing a value into a smaller type likesqrtf (M_PI)๐. It's chill about explicit casts likeabs ((int) x)andui = (unsigned) -1๐ซถ (you meant it, bestie), and it won't yell if the value doesn't actually change, likeabs (2.0). If the signed/unsigned warnings are too much, you can turn just those off with-Wno-sign-conversion๐
For C++, it also flags confusing overload resolution for user-defined conversions ๐ฅ, plus conversions that never use a type conversion operator: conversions to void, the same type, a base class, or a reference to them ๐ง In C++, the signed/unsigned conversion warnings are off by default unless you explicitly enable -Wsign-conversion ๐ญ
Warnings about arithmetic on a small type getting converted back to that same small type only show up with -Warith-conversion ๐ธ
-Wdangling-elseโ this one is for the "wait, whichifdoes thiselsebelong to??" moments ๐ Here's the classic example that gets people:
{
if (a)
if (b)
foo ();
else
bar ();
}
In C/C++, every else belongs to the innermost possible if, which in this example is if (b) ๐ญ That's usually NOT what the programmer meant, even though the indentation says otherwise. When there's a chance of this mix-up, GCC warns if you turn this flag on. To make the warning go away, add explicit braces around the innermost if so the else can't possibly belong to the outer one โจ The fixed code looks like this:
{
if (a)
{
if (b)
foo ();
else
bar ();
}
}
This warning is enabled by -Wparentheses ๐
-Wdate-timeโ warns when the macros__TIME__,__DATE__or__TIMESTAMP__show up, because they can stop you from getting bit-wise-identical reproducible compilations ๐ฐ๏ธ๐-Wempty-bodyโ warns if there's an empty body in anif,elseordo whilestatement ๐ซง This one's also turned on by-Wextraโจ-Wno-endif-labelsโ stops GCC from fussing about stray tokens after#elseand#endif๐ฆ-Wenum-compareโ warns when you compare values from different enumerated types ๐ In C++, mismatched enum types in conditional expressions get flagged too, and this one is on by default there. In C, it's turned on by-Wall๐-Wenum-conversion(C, Objective-C only) โ warns when a value of one enumerated type gets implicitly converted into a different enumerated type ๐ Enabled by-Wextra๐-Wjump-misses-init(C, Objective-C only) โ this is aboutgotoandswitchstatements that jump forward across a variable's initialization, or jump backward to a label after that variable's already been initialized ๐ง It only cares about variables that get initialized right when they're declared. This warning is only supported for C and Objective-C, because in C++ this kind of branch is an error anyway ๐
-Wjump-misses-init is included in -Wc++-compat, and you can turn it off with -Wno-jump-misses-init ๐ซถ
-Wsign-compareโ warns when a comparison between signed and unsigned values could give an incorrect result because the signed value gets converted to unsigned ๐ In C++, this one's enabled by-Wall. In C, it's enabled by-Wextra๐ฅ-Wsign-conversionโ warns for implicit conversions that might change the sign of an integer value, like assigning a signed integer expression to an unsigned integer variable ๐ธ An explicit cast silences the warning โจ In C, this option is also turned on by-Wconversion๐-Wfloat-conversionโ warns for implicit conversions that reduce the precision of a real value ๐ That includes going from real to integer, and going from a higher precision real to a lower precision real. This option is also turned on by-Wconversion๐ฆ-Wno-scalar-storage-orderโ tells GCC to chill about suspicious constructs involving reverse scalar storage order ๐-Wsizeof-pointer-divโ warns about suspicious divisions of twosizeofexpressions that divide the pointer size by the element size ๐ That's the usual way people try to compute an array size, but it won't work right with pointers. For example, this warns aboutsizeof (ptr) / sizeof (ptr[0])ifptris a pointer and not an array ๐ญ Enabled by-Wallโจ-Wsizeof-pointer-memaccessโ warns about sketchy length parameters passed to certain string and memory built-in functions when the argument usessizeof๐ง It triggers for things likememset (ptr, 0, sizeof (ptr));ifptris a pointer and not an array (and it even suggests a possible fix), ormemcpy (&foo, ptr, sizeof (&foo));๐ It also warns about bounded string copy functions likestrncatorstrncpythat use thesizeofof the source array as their bound. Here's a super relatable example where thestrncatcall uses the size of the source string as the bound. That's almost certainly a mistake, so the call gets diagnosed ๐
void make_file (const char *name)
{
char path[PATH_MAX];
strncpy (path, name, sizeof path - 1);
strncat (path, ".text", sizeof ".text");
...
}
The-Wsizeof-pointer-memaccessoption is enabled by-Wall๐
-Wno-sizeof-array-argumentโ doesn't warn whensizeofgets applied to a parameter that's declared as an array in a function definition ๐ This warning is enabled by default for C and C++ programs ๐ธ-Wmemset-elt-sizeโ warns about suspicious calls to thememsetbuilt-in function. It triggers when the first argument references an array, and the third argument is a number equal to the number of elements, but not equal to the size of the array in memory ๐ญ That usually means you forgot to multiply by the element size. This warning is enabled by-Wallโจ-Wmemset-transposed-argsโ warns about suspiciousmemsetcalls where the second argument isn't zero and the third argument is zero ๐ For example,memset (buf, sizeof buf, 0)gets diagnosed, becausememset (buf, 0, sizeof buf)was what you meant ๐ The diagnostic only fires if the third argument is a literal zero. If it's an expression that folds to zero, or a cast of zero to some type, the arguments are a lot less likely to have been mixed up by accident, so no warning is emitted ๐ซถ This warning is enabled by-Wall๐ฅ-Waddressโ warns about suspicious uses of memory addresses ๐ This includes using the address of a function in a conditional expression, likevoid func(void); if (func), and comparing against the memory address of a string literal, likeif (x == "abc"). These usually mean a programmer error. The address of a function always evaluates to true, so using it in a conditional usually means you forgot the parentheses in a function call ๐ And comparing against string literals gives unspecified behavior and isn't portable in C, so you probably meant to usestrcmp๐ง This warning is enabled by-Wallโจ-Wno-address-of-packed-memberโ doesn't warn when the address of a packed member of a struct or union is taken, which usually results in an unaligned pointer value ๐ฆ This is enabled by default ๐-Wlogical-opโ warns about suspicious uses of logical operators in expressions ๐ That includes using logical operators where a bit-wise operator is likely expected. It also warns when both operands of a logical operator are the same. Like this one:
extern int a;
if (a < 0 && a < 0) { ... }
-Wlogical-not-parenthesesโ warns about a logical not used on the left-hand operand of a comparison ๐ It doesn't warn if the right operand is considered a boolean expression. The point is to catch sketchy code like this:
int a;
...
if (!a > 1) { ... }
If you want to shut the warning up, wrap the left-hand side in parentheses:
if ((!a) > 1) { ... }
This warning is enabled by -Wall ๐
-Waggregate-returnโ warns if any functions that return structures or unions are defined or called ๐ In languages where you can return an array, this also gets a warning ๐-Wno-aggressive-loop-optimizationsโ warns if, inside a loop with a constant number of iterations, the compiler detects undefined behavior in some statement during one or more of the iterations ๐ฅ-Wno-attributesโ doesn't warn if an unexpected__attribute__is used, like unrecognized attributes, function attributes applied to variables, and so on ๐ง This doesn't stop errors for incorrect use of supported attributes though, so don't get too comfy ๐-Wno-builtin-declaration-mismatchโ warns if a built-in function is declared with an incompatible signature or as a non-function ๐ It also warns when a built-in function declared with a type that doesn't include a prototype gets called with arguments whose promoted types don't match what the function expects. With-Wextraon, it also warns when a built-in function that takes arguments is declared without a prototype ๐ธ The-Wbuiltin-declaration-mismatchwarning is enabled by default. To avoid it, include the appropriate header so the prototypes of built-in functions are in scope โจ
Here's an example. The call to memset below gets diagnosed because the function expects a value of type size_t as its argument, but the type of 32 is int ๐ญ With -Wextra, the declaration of the function gets diagnosed too:
extern void* memset ();
void f (void *d)
{
memset (d, '\0', 32);
}
-Wno-builtin-macro-redefined: okay bestie, this is the chill button ๐ It stops GCC from freaking out when you redefine certain built-in macros. Specifically, it quiets the warnings for redefining__TIMESTAMP__,__TIME__,__DATE__,__FILE__, and__BASE_FILE__๐ฐ๏ธ-Wstrict-prototypes(C and Objective-C only): GCC will call you out if a function gets declared or defined without spelling out its argument types ๐ An old-style definition gets a pass with no warning, though, as long as an earlier declaration already lists the argument types. no cap, that's a fair deal ๐ซถ-Wold-style-declaration(C and Objective-C only): this one hunts for obsolescent stuff in declarations, based on the C Standard ๐ For example, it warns if storage-class specifiers likestaticaren't the very first things in a declaration. This warning is also enabled by-Wextraโจ-Wold-style-definition(C and Objective-C only): warns whenever you use an old-style function definition, and it does this even if there's a previous prototype ๐ Quick tea โ: a definition using()isn't treated as old-style in C2X mode, since it means the same thing as(void)there. For older standards, though, it still counts as old-style.-Wmissing-parameter-type(C and Objective-C only): this catches a parameter that gets declared with no type specifier in K&R-style functions, like this ๐
void foo(bar) { }
This warning is also enabled by -Wextra ๐ธ
-Wmissing-prototypes(C and Objective-C only): warns if a global function is defined without a previous prototype declaration ๐ฆ It fires even when the definition itself has a prototype. Use it to sniff out global functions that don't have a matching prototype in a header file. This option isn't valid for C++, because every function declaration there already provides a prototype, and a non-matching one just declares an overload instead of conflicting with an earlier declaration. For C++, use-Wmissing-declarationsinstead ๐-Wmissing-declarations: warns if a global function is defined without a previous declaration ๐ง Same deal, it does this even if the definition provides a prototype. Use it to find global functions that aren't declared in header files. In C, there are no warnings for functions with previous non-prototype declarations, so use-Wmissing-prototypesfor those. In C++, there are no warnings for function templates, inline functions, or functions in anonymous namespaces ๐-Wmissing-field-initializers: warns if a structure's initializer is missing some fields ๐ In this example,x.his implicitly zero, so it gets flagged:
struct s { int f, g, h; };
struct s x = { 3, 4 };
This option does not warn about designated initializers, so this one slides right through โจ
struct s { int f, g, h; };
struct s x = { .f = 3, .g = 4 };
In C, this option also doesn't warn about the universal zero initializer { 0 } ๐
struct s { int f, g, h; };
struct s x = { 0 };
Likewise, in C++, the empty { } initializer gets a pass too ๐ซถ
struct s { int f, g, h; };
s x = { };
This warning is included in -Wextra. If you want the other -Wextra warnings without this one, use -Wextra -Wno-missing-field-initializers ๐
-Wno-multichar: turns off the warning for multicharacter constants like'FOOF'๐ These are usually typos, since they have implementation-defined values, so they don't belong in portable code ๐-Wnormalized=[none|id|nfc|nfkc]: okay, this one is a whole saga, so buckle up ๐ข In ISO C and ISO C++, two identifiers are different if they're different sequences of characters. But when characters outside basic ASCII show up, you can end up with two different sequences that look exactly the same ๐ To stop that confusion, the ISO 10646 standard has normalization rules that turn look-alike sequences into the same sequence. GCC can warn you if your identifiers haven't been normalized, and this option controls that warning.
There are four levels of warning supported by GCC. The default is -Wnormalized=nfc, which warns about any identifier that isn't in the ISO 10646 "C" normalized form, NFC. NFC is the recommended form for most uses, and it's equivalent to -Wnormalized ๐
Here's the tea: some characters that ISO C and ISO C++ allow in identifiers can't be allowed after converting to NFC. That means there's no way to use those symbols in portable ISO C or C++ and still have every identifier in NFC ๐ญ -Wnormalized=id suppresses the warning for those characters. The standards folks are hoping future versions will fix this, which is exactly why this option isn't the default โจ
You can switch the warning off for all characters with -Wnormalized=none or -Wno-normalized.
Only do this if you're using some other normalization scheme (like "D"). Otherwise you can easily create bugs that are literally impossible to see ๐
Some characters in ISO 10646 have distinct meanings but look identical in some fonts or display methods, especially after formatting has been applied ๐ธ For instance, "\u207F" (SUPERSCRIPT LATIN SMALL LETTER N) displays just like a regular "n" placed in a superscript. ISO 10646 defines the NFKC normalization scheme to convert all of these into a standard form too, and GCC warns if your code isn't in NFKC when you use -Wnormalized=nfkc. This is kind of like warning about every identifier that contains the letter O, since it might be mixed up with the digit 0. That's why it isn't the default, but it can be a useful local coding convention if your programming environment can't be fixed to display these characters distinctly ๐ฅ
-Wno-attribute-warning: stops GCC from warning about usage of functions declared with the "warning" attribute ๐ฆ By default, this warning is enabled. You can use-Wno-attribute-warningto disable the warning, or-Wno-error=attribute-warningto disable the error when compiling with the-Werrorflag ๐ซถ-Wno-deprecated: no warnings about usage of deprecated features ๐ง-Wno-deprecated-declarations: no warnings about uses of functions, variables, and types marked as deprecated with the "deprecated" attribute ๐-Wno-overflow: no warnings about compile-time overflow in constant expressions ๐-Wno-odr: this one warns about One Definition Rule violations during link-time optimization ๐ง It's enabled by default โจ-Wopenmp-simd: warns if the vectorizer cost model overrides the OpenMP simd directive that you set ๐ If you want to relax the cost model, you can use-fsimd-cost-model=unlimited๐-Woverride-init(C and Objective-C only): warns if an initialized field without side effects gets overridden when you use designated initializers ๐ This warning is included in-Wextra. To get the other-Wextrawarnings without this one, use-Wextra -Wno-override-init๐-Wno-override-init-side-effects(C and Objective-C only): no warnings if an initialized field with side effects gets overridden when you use designated initializers. This warning is enabled by default ๐-Wpacked: warns if a structure gets the packed attribute, but packed has no effect on the layout or size of the structure ๐ง Those structures can end up misaligned for little benefit, which is a bit of a mood ๐ฌ In this code, the variablef.xinstruct baris misaligned, even thoughstruct bardoesn't have the packed attribute itself:
struct foo {
int x;
char a, b, c, d;
} __attribute__((packed));
struct bar {
char z;
struct foo f;
};
-Wnopacked-bitfield-compat: okay, history lesson time ๐ The 4.1, 4.2, and 4.3 series of GCC ignored the packed attribute on bit-fields of typechar. That got fixed in GCC 4.4, but the change can lead to differences in structure layout. GCC tells you when the offset of such a field has changed in GCC 4.4. For example, there's no longer a 4-bit padding between fieldaandbin this structure:
struct foo
{
char a:4;
char b:8;
} __attribute__ ((packed));
This warning is enabled by default. Use -Wno-packed-bitfield-compat to disable this warning ๐ธ
-Wpacked-not-aligned(C, C++, Objective-C and Objective-C++ only): warns if a structure field with explicitly specified alignment inside a packed struct or union is misaligned โญ For example, a warning gets issued onstruct S, like, "warning: alignment 1 of 'struct S' is less than 8", in this code:
struct __attribute__ ((aligned (8))) S8 { char a[8]; };
struct __attribute__ ((packed)) S {
struct S8 s8;
};
This warning is enabled by -Wall ๐ฅ
-Wpadded: warns if padding is included in a structure, either to align one of its elements or to align the whole structure ๐ซง Sometimes you can rearrange the fields to reduce the padding and make the structure smaller, so this one is kind of a helpful nudge ๐ฆ-Wredundant-decls: warns if anything gets declared more than once in the same scope ๐ It does this even in cases where multiple declarations are valid and change nothing ๐-Wrestrict: warns when an object referenced by arestrict-qualified parameter (or a__restrict-qualified parameter in C++) is aliased by another argument, or when copies between those objects overlap ๐ฑ In thestrcpyexample below, the call tries to truncate the string by replacing its initial characters with the last four. But because the call writes the terminating NUL intoa[4], the copies overlap, and the call gets diagnosed ๐
void foo (void)
{
char a[] = "abcd1234";
strcpy (a, a + 4);
...
}
The -Wrestrict option detects some instances of simple overlap even without optimization, but it works best at -O2 and above โก It's included in -Wall ๐
-Wnested-externs(C and Objective-C only): warns if anexterndeclaration is encountered within a function ๐-Winlineโ okay so this one yells at you if a function you markedinlinecan't actually get inlined ๐ Even with it on, GCC won't warn about failed inlining in functions from system headers ๐ซถ The compiler juggles a bunch of heuristics to decide, like how big the function is and how much inlining it's already done in the current function. So tiny changes in your source can make-Winlinewarnings pop up or vanish, and that's just the vibe ๐ฆ-Wint-in-bool-contextโ warns about sus integer stuff where a boolean is expected ๐ง Think conditional expressions (?:) using non-boolean integer constants in a boolean context, like"if (a <= b ? 2 : 3)". Or left shifting signed integers in a boolean context, like"for (a = 0; 1 << a; a++);". It also covers all kinds of multiplications, no matter the data type ๐ This one is enabled by-Wallโจ-Wno-int-to-pointer-castโ this suppresses the warnings for casts to a pointer type from an integer of a different size ๐ In C++, casting to a pointer type of a smaller size is an error, so keep that in mind bestie.Wint-to-pointer-castis enabled by default ๐-Wno-pointer-to-int-cast(C and Objective-C only) โ silences warnings for casts from a pointer to an integer type of a different size ๐ธ-Winvalid-pchโ warns if a precompiled header is found in the search path but can't actually be used ๐ฅฒ-Wlong-longโ warns when the"long long"type shows up ๐ It's enabled by either-Wpedanticor-Wtraditionalin ISO C90 and C++98 modes. To make the warnings go away, use-Wno-long-long๐-Wvariadic-macrosโ warns if variadic macros are used in ISO C90 mode, or if the GNU alternate syntax is used in ISO C99 mode ๐ง It's enabled by either-Wpedanticor-Wtraditional. To shush it, use-Wno-variadic-macros๐ซถ-Wno-varargsโ don't warn about questionable usage of the macros for handling variable arguments, like"va_start"๐ These warnings are on by default, so this is how you turn them off ๐ โโ๏ธ-Wvector-operation-performanceโ warns if a vector operation isn't implemented using the architecture's SIMD capabilities ๐ฅ It's mainly useful for performance tuning. A vector operation can be done three ways: "piecewise", where the scalar operation runs on every vector element; "in parallel", where it's implemented with scalars of a wider type (which is usually more performance efficient); and "as a single scalar", where the vector fits into a scalar type โจ-Wvlaโ warns if a variable-length array is used in the code ๐ฆ-Wno-vlastops the-Wpedanticwarning about variable-length arrays ๐-Wvla-larger-than=byte-sizeโ if you use this, the compiler warns about declarations of variable-length arrays whose size is either unbounded, or bounded by an argument that lets the array size go past byte-size bytes ๐ญ It's kinda like how-Walloca-larger-than=byte-sizeworks, just for variable-length arrays ๐
Heads up: GCC may optimize small variable-length arrays with a known value into plain arrays, so this warning might not trigger for those ๐
-Wvla-larger-than=PTRDIFF_MAX is enabled by default, but it's typically only effective when -ftree-vrp is active (which is the default for -O2 and above) ๐ง See also -Walloca-larger-than=byte-size โญ
-Wno-vla-larger-thanโ disables the-Wvla-larger-than=warnings ๐ โโ๏ธ This is the same as-Wvla-larger-than=SIZE_MAXor larger ๐ธ-Wvolatile-register-varโ warns if a register variable is declaredvolatile๐ซ Here's the tea:volatiledoesn't stop every optimization that might eliminate reads and/or writes to register variables. This warning is enabled by-Wall๐-Wdisabled-optimizationโ warns if a requested optimization pass is disabled ๐ฅน This doesn't usually mean your code is wrong. It just means GCC's optimizers can't handle it efficiently. Often the code is just too big or too complex, and GCC refuses to optimize programs when the optimization would likely take inordinate amounts of time ๐ข-Wpointer-sign(C and Objective-C only) โ warns about pointer argument passing or assignment with different signedness ๐ This option is only supported for C and Objective-C. It's implied by-Walland by-Wpedantic, and you can disable it with-Wno-pointer-sign๐-Wstack-protectorโ this one is only active when-fstack-protectoris active ๐ก๏ธ It warns about functions that aren't protected against stack smashing ๐-Woverlength-stringsโ warns about string constants longer than the "minimum maximum" length the C standard specifies ๐ Modern compilers are chill with way longer strings, but very portable programs should avoid them ๐ซถ The limit applies after string constant concatenation and doesn't count the trailing NUL. In C90 the limit was 509 characters, and in C99 it got bumped to 4095. C++98 doesn't specify a normative minimum maximum, so GCC doesn't diagnose overlength strings in C++ ๐ This option is implied by-Wpedantic, and you can disable it with-Wno-overlength-stringsโจ-Wunsuffixed-float-constants(C and Objective-C only) โ issues a warning for any floating constant without a suffix ๐ง If you pair it with-Wsystem-headers, it also warns about those constants in system header files. This is super handy when you're getting code ready for the"FLOAT_CONST_DECIMAL64"pragma from the decimal floating-point extension to C99 ๐-Wno-lto-type-mismatchโ during link-time optimization, this stops warnings about type mismatches in global declarations from different compilation units ๐ It requires-fltoto be enabled, and it's on by default ๐ฆ-Wno-designated-init(C and Objective-C only) โ suppresses warnings when a positional initializer is used to initialize a structure marked with the"designated_init"attribute ๐-Wno-hsaโ no warnings when HSAIL can't be emitted for the compiled function or OpenMP construct ๐ธ These warnings are on by default, so this is how you quiet them ๐
โจ Options That Control Static Analysis โจ
-fanalyzerโ okay this one is the main character of static analysis ๐ต๏ธโโ๏ธ It looks for "interesting" interprocedural paths through the code and warns you about problems it finds on them. Just a heads up, it's way more expensive than other GCC warnings ๐ญ Turning it on effectively turns on all of these:
-Wanalyzer-double-fclose -Wanalyzer-double-free
-Wanalyzer-exposure-through-output-file -Wanalyzer-file-leak
-Wanalyzer-free-of-non-heap -Wanalyzer-malloc-leak
-Wanalyzer-possible-null-argument
-Wanalyzer-possible-null-dereference -Wanalyzer-null-argument
-Wanalyzer-null-dereference -Wanalyzer-stale-setjmp-buffer
-Wanalyzer-tainted-array-index
-Wanalyzer-unsafe-call-within-signal-handler
-Wanalyzer-use-after-free
-Wanalyzer-use-of-pointer-in-stale-stack-frame
This option is only available if GCC was configured with analyzer support enabled, so check your build first ๐
-Wanalyzer-too-complexโ the analyzer uses a bunch of heuristics to explore the control flow and data flow in your program, but sufficiently complicated code can totally defeat them ๐ By default, if the code is too complicated and the analysis hits an internal limit, it just silently stops ๐คทโโ๏ธ This option makes it warn you when that happens ๐ฅ-Wno-analyzer-double-fcloseโ this warning needs-fanalyzerto be on, since that's what enables it ๐ Use-Wno-analyzer-double-fcloseto turn it off. It warns about paths through the code where a"FILE *"can have"fclose"called on it more than once ๐-Wno-analyzer-double-freeโ again, this needs-fanalyzerto enable it, and you can use-Wno-analyzer-double-freeto disable it ๐ซถ It warns about paths where a pointer can have"free"called on it more than once ๐งน-Wno-analyzer-exposure-through-output-fileโ needs-fanalyzerto be enabled, and-Wno-analyzer-exposure-through-output-fileturns it off ๐ It warns about paths where a security-sensitive value gets written to an output file, like writing a password to a log file ๐ (no thank you ๐)-Wno-analyzer-file-leakโ requires-fanalyzer, and you can disable it with-Wno-analyzer-file-leak๐ธ It warns about paths where a"<stdio.h>" "FILE *"stream object gets leaked ๐ง-Wno-analyzer-free-of-non-heapโ needs-fanalyzerto be on, and-Wno-analyzer-free-of-non-heapdisables it ๐ง It warns about paths where"free"is called on a non-heap pointer, like an on-stack buffer or a global ๐ โโ๏ธ-Wno-analyzer-malloc-leakโ-fanalyzerenables this one, and-Wno-analyzer-malloc-leakturns it off โจ It warns about paths where a pointer allocated via"malloc"gets leaked ๐ซ-Wno-analyzer-possible-null-argumentโ requires-fanalyzer, and-Wno-analyzer-possible-null-argumentdisables it ๐ It warns about paths where a possibly-NULL value is passed to a function argument marked with"__attribute__((nonnull))"as needing a non-NULL value ๐ฅบ-Wno-analyzer-possible-null-dereferenceโ needs-fanalyzerto be enabled, and-Wno-analyzer-possible-null-dereferenceturns it off ๐ It warns about paths where a possibly-NULL value gets dereferenced ๐ฌ-Wno-analyzer-null-argumentโ-fanalyzerenables this, and-Wno-analyzer-null-argumentdisables it ๐ It warns about paths where a value known to be NULL is passed to a function argument marked with"__attribute__((nonnull))"as needing a non-NULL value ๐-Wno-analyzer-null-dereferenceโ requires-fanalyzer, and you can use-Wno-analyzer-null-dereferenceto disable it ๐ซถ
okay bestie, this one is the alarm for when a path through your code dereferences a value that's known to be NULL ๐ rip to every null pointer that snuck through unnoticed ๐ซ
-Wno-analyzer-stale-setjmp-bufferโ this warning needs-fanalyzerto be on, and that flag turns it on for you โจ if you want it gone, use-Wno-analyzer-stale-setjmp-buffer๐
okay so this one warns when longjmp gets used to rewind to a jmp_buf tied to a setjmp call, but the function that made that setjmp call has already returned ๐ญ
when setjmp is called on a jmp_buf to save a rewind spot, it also records the stack frame. that frame goes invalid the second the function with the setjmp call returns. if you longjmp back to it anyway, you're referencing a stack frame that doesn't exist anymore, which will likely lead to a crash (or worse ๐)
-Wno-analyzer-tainted-array-indexโ this warning needs both-fanalyzerand-fanalyzer-checker=taintto be enabled ๐ use-Wno-analyzer-tainted-array-indexto switch it off
this one is giving security vibes ๐ก๏ธ it warns when a value an attacker could control gets used as the index of an array access without being sanitized first
-Wno-analyzer-unsafe-call-within-signal-handlerโ this warning needs-fanalyzer, which enables it ๐ฅ use-Wno-analyzer-unsafe-call-within-signal-handlerto disable it
it warns when a function that's known to be async-signal-unsafe (like fprintf) gets called from inside a signal handler ๐
-Wno-analyzer-use-after-freeโ this warning needs-fanalyzer, which enables it โจ use-Wno-analyzer-use-after-freeto disable it
this one is the drama queen ๐ it warns when a pointer gets used after free has already been called on it
-Wno-analyzer-use-of-pointer-in-stale-stack-frameโ this warning needs-fanalyzer, which enables it ๐ธ use-Wno-analyzer-use-of-pointer-in-stale-stack-frameto disable it
it warns when a pointer gets dereferenced and it points to a variable in a stale stack frame ๐ฆ
okay so the knobs you can twist to control how the analyzer explores your code are --param analyzer-bb-explosion-factor=value, --param analyzer-max-enodes-per-program-point=value, --param analyzer-max-recursion-depth=value, and --param analyzer-min-snodes-for-call-summary=value ๐๏ธ
these options control the analyzer, so let's get into them ๐
-fanalyzer-call-summariesโ simplifies interprocedural analysis by computing the effect of certain calls, instead of exploring every path through the function from the callsite to each possible return โจ
if enabled, call summaries are only used for functions with more than one call site, and that are sufficiently complicated (as per --param analyzer-min-snodes-for-call-summary=value) ๐ง
-fanalyzer-checker=nameโ restricts the analyzer to run just the named checker, and enables it ๐ฏ
some checkers are off by default (even with -fanalyzer), like the "taint" checker that implements -Wanalyzer-tainted-array-index. this option is required to turn them on ๐
-fanalyzer-fine-grainedโ this one is intended for analyzer developers ๐งโ๐ป
internally the analyzer builds an "exploded graph" that combines control flow graphs with data flow information. by default, an edge in this graph can hold the effects of a whole run of multiple statements within a basic block. with -fanalyzer-fine-grained, each statement gets its own edge ๐ฆ
-fanalyzer-show-duplicate-countโ another developer-only one ๐ ๏ธ if multiple diagnostics get flagged as duplicates of each other, it emits a note when reporting the best diagnostic, giving the number of extra diagnostics the deduplication logic suppressed ๐-fno-analyzer-state-mergeโ developer territory ๐ by default the analyzer tries to simplify things by merging sufficiently similar states at each program point as it builds its "exploded graph". with-fno-analyzer-state-mergethis merging gets suppressed, which is handy for debugging state-handling issues ๐-fno-analyzer-state-purgeโ also for developers ๐ง by default the analyzer purges aspects of state at a program point that seem no longer relevant, like the values of locals that aren't accessed later in the function and don't matter for leak analysis. with-fno-analyzer-state-purgethis purging gets suppressed, for debugging state-handling issues ๐ซถ-fanalyzer-transitivityโ enables transitivity of constraints within the analyzer ๐-fanalyzer-verbose-edgesโ developer-only, and it's giving extra detail ๐ค it enables more verbose, lower-level detail in the descriptions of control flow within diagnostic paths-fanalyzer-verbose-state-changesโ developer-only, same energy ๐ฌ it enables more verbose, lower-level detail in the descriptions of state machine events within diagnostic paths-fanalyzer-verbosity=levelโ controls how complex the control flow paths are that get emitted for analyzer diagnostics ๐
the level can be one of:
0โ at this level, interprocedural call and return events get displayed, along with the most pertinent state-change events for a diagnostic. for example, for a double-"free" diagnostic, both calls to "free" will be shown ๐ธ1โ same as the level above, but also shows events for the entry to each function ๐ช2โ same as the level above, but also shows control flow events that matter for triggering the issue (like "true path taken" at a conditional) โจ this level is the default ๐3โ same as the level above, but shows all control flow events, not just the significant ones ๐4โ developer-only ๐งช adds various other events intended for debugging the analyzer
-fdump-analyzerโ dumps internal details about what the analyzer is doing tofile.analyzer.txt๐ this option is overridden by-fdump-analyzer-stderr-fdump-analyzer-stderrโ dumps internal details about what the analyzer is doing tostderr๐ข this option overrides-fdump-analyzer-fdump-analyzer-callgraphโ dumps a call graph representation suitable for viewing with GraphViz tofile.callgraph.dot๐บ๏ธ-fdump-analyzer-exploded-graphโ dumps an "exploded graph" representation suitable for viewing with GraphViz tofile.eg.dot๐จ nodes are color-coded based on state-machine states to emphasize state changes ๐-fdump-analyzer-exploded-nodesโ emits diagnostics showing where nodes in the "exploded graph" sit in relation to the program source ๐-fdump-analyzer-exploded-nodes-2โ dumps a textual representation of the "exploded graph" tofile.eg.txt๐-fdump-analyzer-exploded-nodes-3โ dumps a textual representation of the "exploded graph" to one dump file per node, namedfile.eg-id.txt๐ญ this is typically a large number of dump files-fdump-analyzer-state-purgeโ same idea as-fdump-analyzer-supergraph, a supergraph suitable for GraphViz, but annotated with info on what state will be purged at each node ๐งน the graph is written tofile.state-purge.dot-fdump-analyzer-supergraphโ dumps representations of the "supergraph" suitable for GraphViz tofile.supergraph.dotandfile.supergraph-eg.dot๐ธ๏ธ these show all the control flow graphs in the program, with interprocedural edges for calls and returns. the second dump has annotations showing nodes in the "exploded graph" and the diagnostics attached to them ๐
โจ Options for Debugging Your Program โจ
okay bestie, to get GCC to emit extra info for a debugger, you almost always just need to add -g to your other options ๐
GCC lets you use -g with -O ๐
but heads up, the shortcuts optimized code takes can be a little surprising. some variables you declared may not exist at all, flow of control may briefly jump somewhere you didn't expect, some statements may not run because they compute constant results or their values are already at hand, and some statements may run in different places because they got moved out of loops ๐ตโ๐ซ the good news is it's still possible to debug optimized output, which makes it reasonable to use the optimizer for programs that might have bugs ๐ซถ
if you're not using some other optimization option, consider using -Og with -g โจ with no -O option at all, some compiler passes that collect debugging-useful info don't run at all, so -Og may give you a better debugging experience ๐ง
-gโ produces debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF) ๐ GDB can work with this debugging information
on most systems that use stabs format, -g turns on extra debugging information that only GDB can use. this extra info makes debugging work better in GDB, but it probably makes other debuggers crash or refuse to read the program ๐ if you want to be certain about whether the extra info gets generated, use -gstabs+, -gstabs, -gxcoff+, -gxcoff, or -gvms (see below) ๐
-ggdbโ produces debugging information for GDB ๐ it uses the most expressive format available (DWARF, stabs, or the native format if neither of those is supported), including GDB extensions if at all possible ๐-gdwarf,-gdwarf-versionโ produces debugging information in DWARF format (if that's supported) ๐ฆ the value of version may be 2, 3, 4 or 5, and the default version for most targets is 4 ๐ DWARF Version 5 is only experimental ๐งช
okay so with DWARF Version 2, some ports require and always use some non-conflicting DWARF 3 extensions in the unwind tables ๐งฉ
Version 4 may require GDB 7.0 and -fvar-tracking-assignments for maximum benefit ๐
GCC no longer supports DWARF Version 1, which is substantially different from Version 2 and later ๐
โโ๏ธ for historical reasons, some other DWARF-related options such as -fno-dwarf2-cfi-asm) still have a reference to DWARF Version 2 in their names, but they apply to all currently-supported versions of DWARF ๐ธ
-gstabs: Okay, this one gives you stabs debug info (if your setup supports it ๐ฅบ), but without the GDB extras ๐ . It's the format DBX uses on most BSD systems. Heads up: on MIPS, Alpha and System V Release 4 systems, this produces stabs output that DBX literally can't read ๐ญ. On System V Release 4 it also needs the GNU assembler ๐ง.-gstabs+: Same stabs vibe, but now with GNU extensions that only the GNU debugger (GDB) understands ๐ค. ngl, other debuggers might crash or refuse to open your program ๐, so use this one with care.-gxcoff: XCOFF format (if supported) ๐ธ. This is the one DBX uses on IBM RS/6000 systems.-gxcoff+: XCOFF with GNU extensions that only GDB gets ๐ง. Same warning as-gstabs+: other debuggers may crash or refuse to read the program. It can also make assemblers that aren't the GNU assembler (GAS) throw an error โ ๏ธ.-gvms: Alpha/VMS debug format (if supported) ๐ฆ. This is what DEBUG uses on Alpha/VMS systems.-glevel,-ggdblevel,-gstabslevel,-gxcofflevel,-gvmslevel: These ask for debug info and let you pick how much ๐. The default level is2โจ.- Level 0 gives you zero debug info. So
-g0cancels out-g๐ โโ๏ธ. - Level 1 is the minimal, bare-bones version ๐. It has enough for backtraces in parts of the program you're not planning to debug. You get descriptions of functions and external variables, plus line number tables, but no info about local variables.
- Level 3 is the full-on version ๐. It adds extra stuff, like every macro definition in the program. Some debuggers support macro expansion when you use
-g3๐ฅ.
- Level 0 gives you zero debug info. So
If you stack up multiple -g options, with or without level numbers, only the last one counts ๐ซถ. The rest get ignored.
Also, -gdwarf doesn't accept a concatenated debug level, so it won't get confused with -gdwarf-level ๐. If you want a different DWARF debug level, just add an extra -glevel option instead ๐.
-fno-eliminate-unused-debug-symbols: By default, no debug info gets made for symbols that never actually get used ๐งน. Pass this if you want debug info for all symbols, used or not โจ.-femit-class-debug-always: Normally GCC puts the debug info for a C++ class in just one object file. This flag says "nah, put it in every object file that uses the class" ๐ฆ. Only reach for this if your debugger can't handle the usual way GCC does classes ๐ค. Heads up, it can make the debug info up to a factor of two bigger ๐.-fno-merge-debug-strings: This tells the linker to not squish together identical strings in the debug info across different object files ๐ . Merging isn't supported by every assembler or linker, fr fr. It makes the debug info smaller in the output file, but link time goes up. Merging is turned on by default ๐ .-fdebug-prefix-map=old=new: When you compile files living in directoryold, the debug info will describe them as if they lived in directorynewinstead ๐บ๏ธ. This is handy for swapping a build-time path for an install-time path. You can also turn an absolute path into a relative one by using.fornew. It can make builds more reproducible and location independent ๐, but you might need an extra command to tell GDB where to find the source files. See also-ffile-prefix-map.-fvar-tracking: This runs the variable tracking pass, which figures out where variables are stored at each point in the code ๐ต๏ธโโ๏ธ. The result is better debug info (if your debug format supports it) ๐. It's on by default when you compile with optimization (-Os,-O,-O2, ...), debug info (-g), and a debug format that supports it.-fvar-tracking-assignments: This annotates assignments to user variables early in compilation and tries to carry those annotations all the way to the end ๐. The goal is better debug info while optimizing. Using-gdwarf-4alongside it is recommended ๐. You can turn it on even when var-tracking is off, but then the annotations get created and maintained and thrown away at the end ๐๏ธ. By default, it's enabled together with-fvar-tracking, except when selective scheduling is enabled.-gsplit-dwarf: This pulls as much DWARF debug info as possible out into a separate output file with a.dwoextension ๐ฆ. It lets your build system skip linking files that have debug info ๐โโ๏ธ. To be useful, you need a debugger that can read.dwofiles ๐ซถ.-gdescribe-dies: Adds description attributes to some DWARF DIEs that don't have a name attribute ๐ท๏ธ. Think artificial variables, external references and call site parameter DIEs.-gpubnames: Generates the DWARF.debug_pubnamesand.debug_pubtypessections ๐.-ggnu-pubnames: Generates.debug_pubnamesand.debug_pubtypesin a format that can be converted into a GDB index ๐ง . Heads up: this only helps if you have a linker that can produce GDB index version 7 ๐.-fdebug-types-section: With DWARF Version 4 or higher, type DIEs can get their own.debug_typessection instead of living in.debug_info๐๏ธ. This is more efficient, because the linker can put them in a separate comdat section and remove duplicates โ๏ธ. But not every DWARF consumer supports.debug_typesyet ๐ฌ, and on some objects it makes the debug info bigger instead of smaller ๐.-grecord-gcc-switches,-gno-record-gcc-switches: This one tacks the command-line options that might affect code generation onto theDW_AT_producerattribute in your DWARF debug info ๐ท๏ธ. They get joined with spaces, and also separated from the compiler version with a space. It's on by default ๐. See also-frecord-gcc-switchesfor another way to stash compiler options in the object file.-gstrict-dwarf: Stops you from using extensions from a later DWARF standard version than the one you picked with-gdwarf-version๐. On most targets, using non-conflicting DWARF extensions from later versions is allowed anyway.-gno-strict-dwarf: Lets you use extensions from a later DWARF standard version than the one you picked with-gdwarf-version๐.-gas-loc-support: Tells the compiler that your assembler supports.locdirectives ๐ง. The compiler can then use them so the assembler generates DWARF2+ line number tables. This is usually what you want, because assembler-generated line number tables are way more compact than the ones the compiler makes itself ๐ค. This gets turned on by default if, at GCC configure time, the assembler was found to support those directives.-gno-as-loc-support: Forces GCC to generate DWARF2+ line number tables internally, if they're meant to be generated at all ๐ โโ๏ธ.-gas-locview-support: Tells the compiler that your assembler supports"view"assignment and reset assertion checking in.locdirectives ๐. It's turned on by default if, at GCC configure time, the assembler was found to support them.-gno-as-locview-support: Forces GCC to assign view numbers internally, if-gvariable-location-viewsgets explicitly requested ๐ง.-gcolumn-info,-gno-column-info: Puts location column info into the DWARF debug info, not just file and line ๐. It's on by default โจ.-gstatement-frontiers,-gno-statement-frontiers: This makes GCC drop markers into the internal representation at the start of statements ๐ฉ. It keeps them roughly in place through compilation and uses them to guide the output ofis_stmtmarkers in the line number table ๐บ๏ธ. It's enabled by default when you compile with optimization (-Os,-O,-O2, ...) and output DWARF 2 debug info at the normal level ๐ .-gvariable-location-views,-gvariable-location-views=incompat5,-gno-variable-location-views: This one adds progressive view numbers, implied from the line number table, onto the variable location lists ๐. Debug info consumers can then inspect state at certain points in the program, even if no instructions for the matching source locations exist there ๐ซ . If the assembler can't handle view numbers in line number tables, the compiler will emit the line number table itself, which makes those tables a bit less compact ๐ฆ. The augmented tables and location lists are fully backward-compatible, so consumers that don't know about these augmentations can still read them, they just won't benefit from them either ๐คทโโ๏ธ.
This is on by default at the normal DWARF 2 debug level, as long as there's assembler support, -fvar-tracking-assignments is enabled, and -gstrict-dwarf is not. If assembler support is missing, it can still be enabled, but then GCC has to output internal line number tables. And if -ginternal-reset-location-views isn't enabled, that will most certainly lead to silently mismatching location views ๐ฑ.
โ ๏ธ Heads up, bestie: there's a proposed representation for view numbers that isn't backward compatible with the location list format from DWARF 5. You can turn it on with -gvariable-location-views=incompat5. This option may be removed in the future, and it's only there as a reference implementation of the proposed representation ๐งช. Debug info consumers aren't expected to support this extended format, and they would be unable to decode location lists that use it ๐.
-ginternal-reset-location-views,-gno-internal-reset-location-viewsโ okay so this one tries to figure out which location views can be dropped from location view lists ๐ฆ. It needs the compiler to have very accurate insn length estimates, which isn't always the case ๐, and it may quietly generate incorrect view lists if your assembler doesn't support location view lists at all. The GNU assembler will flag any such mess-up as a "view number mismatch". This only gets turned on for ports that define a reliable estimation function ๐ซถ.-ginline-points,-gno-inline-pointsโ generates extended debug info for inlined functions โจ. Location view tracking markers get dropped in at inlined entry points, so address and view numbers can be computed and spit out in the debug info. You can turn this on by itself without location views, in which case the view numbers won't be output ๐ธ. It can only be enabled alongside statement frontiers, though, and it's only on by default if location views are on.-gz[=type]โ produces compressed debug sections in DWARF format, if that's supported ๐. If you don't give a type, the default depends on what the assembler and linker can do. type can benone(don't compress debug sections),zlib(zlib compression in ELF gABI format), orzlib-gnu(zlib compression in traditional GNU format) ๐. If the linker can't write compressed debug sections, the option gets rejected. Otherwise, if the assembler doesn't support them,-gzgets silently ignored when producing object files ๐.-femit-struct-debug-baseonlyโ emits debug info for struct-like types only when the base name of the compilation source file matches the base name of the file where the struct is defined ๐ .
This one massively shrinks the debug info, but there's a big potential loss in type information for the debugger, so be careful ๐. For a chiller version, see-femit-struct-debug-reduced. For more detailed control, see-femit-struct-debug-detailed.
This option only works with DWARF debug output.
-femit-struct-debug-reducedโ emits debug info for struct-like types only when the base name of the compilation source file matches the base name of the file where the type is defined, unless the struct is a template or defined in a system header ๐. This one significantly shrinks the debug info too, with some potential loss in type information for the debugger. For a more aggressive option, check out-femit-struct-debug-baseonly. For more detailed control, see-femit-struct-debug-detailed.
This option only works with DWARF debug output.
-femit-struct-debug-detailed[=spec-list]โ lets you pick which struct-like types get debug info ๐. The goal is to cut down on duplicate struct debug info between different object files in the same program. This is the detailed version of-femit-struct-debug-reducedand-femit-struct-debug-baseonly, and it covers most needs.
A specification has the syntax [dir:|ind:][ord:|gen:](any|sys|base|none).
The optional first word limits the spec to structs that are used directly (dir:) or used indirectly (ind:) ๐ง. A struct type counts as used directly when it's the type of a variable or member. Indirect uses come through pointers to structs. So when using an incomplete struct is valid, the use is indirect. An example is struct one direct; struct two * indirect;.
The optional second word limits the spec to ordinary structs (ord:) or generic structs (gen:) ๐ซ . Generic structs are a bit complicated to explain. In C++, these are non-explicit specializations of template classes, or non-template classes within the above. Other programming languages have generics, but -femit-struct-debug-detailed doesn't implement them yet.
The third word specifies the source files for those structs that should get debug info ๐. The values none and any have the normal meaning. The value base means the base of the name of the file where the type declaration appears must match the base of the name of the main compilation file. In practice, that means when compiling foo.c, debug info is generated for types declared in that file and foo.h, but not other header files. The value sys means those types that satisfy base or are declared in system or compiler headers.
You may need to experiment to find the best settings for your app ๐ฅ.
The default is -femit-struct-debug-detailed=all.
This option only works with DWARF debug output.
-fno-dwarf2-cfi-asmโ emits DWARF unwind info as a compiler-generated.eh_framesection, instead of using GAS.cfi_*directives ๐ธ.-fno-eliminate-unused-debug-typesโ normally, when producing DWARF output, GCC skips debug symbol output for types that are nowhere used in the source file being compiled. Sometimes you want debug info for every type declared in a compilation unit, even unused ones ๐. For example, if you want to cast a value to a type that's declared but not actually used in your program in the debugger. More often, though, this just wastes a ton of space ๐ญ.
โจ Options That Control Optimization โจ
These options control various sorts of optimizations ๐.
Without any optimization option, the compiler's goal is to reduce the cost of compilation and make debugging produce the expected results ๐. Statements are independent: if you stop the program with a breakpoint between statements, you can 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 expect from the source code.
Turning on optimization flags makes the compiler attempt to improve performance and/or code size, at the expense of compilation time and possibly your ability to debug the program ๐ค.
The compiler optimizes based on what it knows about the program. Compiling multiple files at once to a single output file lets the compiler use information 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 in this section ๐ .
Most optimizations are completely disabled at -O0, or if an -O level isn't set on the command line, even if individual optimization flags are specified. Similarly, -Og suppresses many optimization passes ๐.
Depending on the target and how GCC was configured, a slightly different set of optimizations may be enabled at each -O level than those listed here. You can invoke GCC with -Q --help=optimizers to find out the exact set enabled at each level ๐.
โจ -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 -fbranch-count-reg -fcombine-stack-adjustments
-fcompare-elim -fcprop-registers -fdce -fdefer-pop -fdelayed-branch
-fdse -fforward-propagate -fguess-branch-probability -fif-conversion
-fif-conversion2 -finline-functions-called-once -fipa-profile
-fipa-pure-const -fipa-reference -fipa-reference-addressable
-fmerge-constants -fmove-loop-invariants -fomit-frame-pointer
-freorder-blocks -fshrink-wrap -fshrink-wrap-separate
-fsplit-wide-types -fssa-backprop -fssa-phiopt -ftree-bit-ccp
-ftree-ccp -ftree-ch -ftree-coalesce-vars -ftree-copy-prop
-ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop
-ftree-fre -ftree-phiprop -ftree-pta -ftree-scev-cprop -ftree-sink
-ftree-slsr -ftree-sra -ftree-ter -funit-at-a-time
โจ -O2 โจ
Optimize even more ๐ฅ. GCC performs nearly all supported optimizations that don't involve a space-speed tradeoff. 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:
-falign-functions -falign-jumps -falign-labels -falign-loops
-fcaller-saves -fcode-hoisting -fcrossjumping -fcse-follow-jumps
-fcse-skip-blocks -fdelete-null-pointer-checks -fdevirtualize
-fdevirtualize-speculatively -fexpensive-optimizations
-ffinite-loops -fgcse -fgcse-lm -fhoist-adjacent-loads
-finline-functions -finline-small-functions -findirect-inlining
-fipa-bit-cp -fipa-cp -fipa-icf -fipa-ra -fipa-sra -fipa-vrp
-fisolate-erroneous-paths-dereference -flra-remat
-foptimize-sibling-calls -foptimize-strlen -fpartial-inlining
-fpeephole2 -freorder-blocks-algorithm=stc
-freorder-blocks-and-partition -freorder-functions
-frerun-cse-after-loop -fschedule-insns -fschedule-insns2
-fsched-interblock -fsched-spec -fstore-merging -fstrict-aliasing
-fthread-jumps -ftree-builtin-call-dce -ftree-pre
-ftree-switch-conversion -ftree-tail-merge -ftree-vrp
Please note the warning under -fgcse about invoking -O2 on programs that use computed gotos ๐จ.
NOTE: In Ubuntu 8.10 and later versions,-D_FORTIFY_SOURCE=2is set by default, and is activated when-Ois set to 2 or higher ๐ก๏ธ. This enables additional compile-time and run-time checks for several libc functions. To disable it, specify either-U_FORTIFY_SOURCEor-D_FORTIFY_SOURCE=0.
โจ -O3 โจ
Optimize yet more ๐ช. -O3 turns on all optimizations specified by -O2, and also turns on the following optimization flags:
-fgcse-after-reload -fipa-cp-clone -floop-interchange
-floop-unroll-and-jam -fpeel-loops -fpredictive-commoning
-fsplit-loops -fsplit-paths -ftree-loop-distribution
-ftree-loop-vectorize -ftree-partial-pre -ftree-slp-vectorize
-funswitch-loops -fvect-cost-model -fvect-cost-model=dynamic
-fversion-loops-for-strides
โจ -O0 โจ
Reduce compilation time and make debugging produce the expected results ๐ธ. This is the default.
โจ -Os โจ
Optimize for size ๐. -Os enables all -O2 optimizations except those that often increase code size:
-falign-functions -falign-jumps -falign-labels -falign-loops
-fprefetch-loop-arrays -freorder-blocks-algorithm=stc
It also turns on -finline-functions ๐
and tells the compiler to tune for code size instead of speed. It also runs extra optimizations that shrink your binary ๐ฆ.
-Ofastโ okay, this is the "disregard strict standards compliance" one ๐ญ It enables all-O3optimizations, and it also turns on optimizations that aren't valid for every standard-compliant program, so be careful bestie ๐. It switches on-ffast-math,-fallow-store-data-racesand the Fortran-specific-fstack-arrays(unless-fmax-stack-var-sizeis specified), and-fno-protect-parenstoo.-Ogโ optimize the debugging experience ๐ This should be your go-to level for the normal edit-compile-debug loop. You get a reasonable amount of optimization while compilation stays fast and debugging stays smooth โจ. It's a better pick than-O0for debuggable code, because some compiler passes that collect debug information are disabled at-O0.
Like -O0, -Og completely disables a bunch of optimization passes, so the individual options that control them do nothing ๐. Otherwise -Og turns on all the -O1 flags except the ones that might mess with debugging:
-fbranch-count-reg -fdelayed-branch -fdse -fif-conversion
-fif-conversion2 -finline-functions-called-once
-fmove-loop-invariants -fssa-phiopt -ftree-bit-ccp -ftree-dse
-ftree-pta -ftree-sra
If you use multiple -O options, with or without level numbers, the last one is the one that counts ๐.
Options like -fflag are machine-independent flags ๐งฉ. Most flags come in positive and negative versions, and the negative form of -ffoo is -fno-foo. The table below only lists one of the forms, the one you'll usually reach for. To get the other one, just remove the no- or add it.
The following options control specific optimizations. They're either switched on by -O options or related to ones that are. Only use these in the rare cases when you want to fine-tune which optimizations get performed ๐.
-fno-defer-popโ for machines that have to pop arguments after a function call, this pops them as soon as each function returns ๐ At-O1and higher,-fdefer-popis the default. That lets arguments pile up on the stack across several calls and then get popped all at once ๐ฅ.-fforward-propagateโ runs a forward propagation pass on RTL ๐ It tries to combine two instructions and checks whether the result can be simplified. If loop unrolling is active, two passes happen, and the second one gets scheduled after loop unrolling. Enabled by default at optimization levels-O,-O2,-O3,-Os.-ffp-contract=styleโ the floating-point contraction knob ๐งฎ-ffp-contract=offdisables floating-point expression contraction.-ffp-contract=fastenables it, such as forming fused multiply-add operations, if the target has native support for them.-ffp-contract=onenables it if the language standard allows it. The default is-ffp-contract=fast.
Heads up:-ffp-contract=onis currently not implemented and is treated the same as-ffp-contract=off๐
-fomit-frame-pointerโ omits the frame pointer in functions that don't need one โจ That skips the instructions that save, set up and restore the frame pointer, and on many targets it also frees up an extra register ๐ธ. On some targets this flag does nothing, because the standard calling sequence always uses a frame pointer, so it can't be omitted.-fno-omit-frame-pointerdoesn't guarantee the frame pointer is used in every function, since several targets always omit it in leaf functions. Enabled by default at-Oand higher.-foptimize-sibling-callsโ optimizes sibling and tail recursive calls ๐ช Enabled at levels-O2,-O3,-Os.-foptimize-strlenโ optimizes various standard C string functions (e.g.strlen,strchrorstrcpy) and their_FORTIFY_SOURCEcounterparts into faster alternatives ๐๏ธ Enabled at levels-O2,-O3.-fno-inlineโ no functions get expanded inline except for the ones marked with the "always_inline" attribute ๐ This is the default when you're not optimizing. Single functions can be exempted from inlining by marking them with the "noinline" attribute ๐ก๏ธ.-finline-small-functionsโ integrates functions into their callers when their body is smaller than the code for the function call itself, so the overall program gets smaller ๐ The compiler heuristically decides which functions are simple enough to be worth it. This applies to all functions, even ones not declared inline. Enabled at levels-O2,-O3,-Os.-findirect-inliningโ also inlines indirect calls that are known at compile time thanks to earlier inlining ๐ง This only has an effect when inlining itself is turned on by-finline-functionsor-finline-small-functions. Enabled at levels-O2,-O3,-Os.-finline-functionsโ considers all functions for inlining, even ones not declared inline ๐ The compiler heuristically decides which ones are worth integrating. If all calls to a given function get integrated and the function is declared "static", then it's normally not output as assembler code on its own. Enabled at levels-O2,-O3,-Os. Also enabled by-fprofile-useand-fauto-profile๐.-finline-functions-called-onceโ considers all "static" functions called once for inlining into their caller, even if they aren't marked "inline" ๐ฏ If a call to a given function gets integrated, the function isn't output as assembler code on its own. Enabled at levels-O1,-O2,-O3and-Os, but not-Og.-fearly-inliningโ inlines functions marked by "always_inline" and functions whose body seems smaller than the function call overhead, early on. This happens before doing-fprofile-generateinstrumentation and the real inlining pass โฉ That makes profiling significantly cheaper, and it usually makes inlining faster in programs with large chains of nested wrapper functions ๐ช. Enabled by default.-fipa-sraโ performs interprocedural scalar replacement of aggregates, removes unused parameters, and replaces parameters passed by reference with parameters passed by value ๐งน Enabled at levels-O2,-O3and-Os.-finline-limit=nโ by default, GCC limits the size of functions that can be inlined ๐ This flag gives you coarse control over that limit.nis the size of functions that can be inlined, measured in pseudo instructions. Inlining is actually controlled by a bunch of parameters, which you can set individually with--param name=value. The-finline-limit=noption sets some of these parameters like this:max-inline-insns-singleโ is set ton/2.max-inline-insns-autoโ is set ton/2.
Check below for the individual inlining parameters and their defaults ๐
Note: there may be no value to -finline-limit that results in default behavior.
Note: "pseudo instruction" means, in this context, an abstract measurement of a function's size ๐งช It is in no way a count of assembly instructions, so its exact meaning might change from one release to another.
-fno-keep-inline-dllexportโ a more fine-grained version of-fkeep-inline-functions, which only applies to functions declared with the "dllexport" attribute or declspec ๐.-fkeep-inline-functionsโ in C, emits "static" functions declared "inline" into the object file, even if they've been inlined into all of their callers ๐ฆ This switch doesn't affect functions using the "extern inline" extension in GNU C90. In C++, it emits any and all inline functions into the object file ๐.-fkeep-static-functionsโ emits "static" functions into the object file, even if they're never used ๐งธ.-fkeep-static-constsโ emits variables declared "static const" when optimization isn't turned on, even if they aren't referenced ๐ GCC enables this option by default. If you want the compiler to check whether a variable is referenced regardless of whether optimization is on, use-fno-keep-static-consts.-fmerge-constantsโ attempts to merge identical constants (string constants and floating-point constants) across compilation units ๐งฉ This is the default for optimized compilation if the assembler and linker support it. Use-fno-merge-constantsto inhibit this behavior ๐ . Enabled at levels-O,-O2,-O3,-Os.-fmerge-all-constantsโ attempts to merge identical constants and identical variables ๐ซ This implies-fmerge-constants. On top of that, it considers things like even constant initialized arrays or initialized constant variables 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 results in non-conforming behavior.
โ ๏ธ Warning: -fmerge-all-constants results in non-conforming behavior, so it's not standards-approved, bestie ๐
-fmodulo-schedโ performs swing modulo scheduling immediately before the first scheduling pass ๐ This pass looks at innermost loops and reorders their instructions by overlapping different iterations.-fmodulo-sched-allow-regmovesโ performs more aggressive SMS-based modulo scheduling with register moves allowed ๐ By setting this flag, certain anti-dependence edges get deleted, which triggers the generation of reg-moves based on life-range analysis. This option is only effective with-fmodulo-schedenabled.-fno-branch-count-regโ disables the optimization pass that scans for chances to use "decrement and branch" instructions on a count register, instead of instruction sequences that decrement a register, compare it against zero, and then branch based on the result โฌ This option is only meaningful on architectures that support such instructions, which include x86, PowerPC, IA-64 and S/390. Note that-fno-branch-count-regdoesn't remove the decrement and branch instructions that other optimization passes introduce into the generated instruction stream ๐
Okay so the default for -fbranch-count-reg is on at -O1 and higher, except for -Og ๐
โจ
-fno-function-cseโ bestie, this one is a little chaotic ๐ It tells GCC to not stash function addresses in registers. Instead, every instruction that calls a constant function spells out the function's address explicitly. The code ends up less efficient, ngl, but some strange hacks that alter the assembler output can get confused by the optimizations you'd get without this flag. The default is-ffunction-cse๐ธ-fno-zero-initialized-in-bssโ if the target has a BSS section, GCC normally tosses variables that start out as zero into BSS, which can save space ๐ง This option turns that off, because some programs explicitly rely on variables living in the data section. For example, they might look for the beginning of that section, or make assumptions based on it ๐ The default is-fzero-initialized-in-bss.-fthread-jumpsโ this is giving jump-chasing ๐ฆ It checks whether a jump lands somewhere another comparison, one that the first comparison already covers, is waiting. If so, the first branch gets redirected to either the destination of the second branch or the spot right after it, depending on whether the condition is known to be true or false. Enabled at levels-O2,-O3,-Os.-fsplit-wide-typesโ when a type takes up multiple registers, likelong longon a 32-bit system, this splits the registers apart and allocates them independently. Usually that gives better code for those types, but it can make debugging harder ๐ฅบ Enabled at levels-O,-O2,-O3,-Os.-fsplit-wide-types-earlyโ splits wide types fully early instead of very late ๐ This does nothing unless-fsplit-wide-typesis turned on. It's the default on some targets.-fcse-follow-jumpsโ during common subexpression elimination (CSE), this scans through jump instructions when nothing else can reach the jump's target. So if there's anifwith anelseclause, CSE follows the jump when the tested condition is false ๐ Enabled at levels-O2,-O3,-Os.-fcse-skip-blocksโ basically a cousin of-fcse-follow-jumps, but this one follows jumps that conditionally skip over blocks. With a simpleifand noelseclause, it follows the jump around the body of theifโญ Enabled at levels-O2,-O3,-Os.-frerun-cse-after-loopโ reruns common subexpression elimination after the loop optimizations are done ๐ Enabled at levels-O2,-O3,-Os.-fgcseโ runs a global common subexpression elimination pass ๐ This pass also does global constant and copy propagation.
Note: When compiling a program that uses computed gotos (a GCC extension), you may get better run-time 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 this is on, global CSE tries to move loads that are only killed by stores into themselves ๐ That means a loop containing a load/store sequence can become a load outside the loop, plus a copy/store inside it. Enabled by default when-fgcseis enabled.-fgcse-smโ when this is on, a store motion pass runs after global CSE ๐ฆ It tries to move stores out of loops. Combined with-fgcse-lm, a loop containing a load/store sequence can become a load before the loop and a store after it. Not enabled at any optimization level.-fgcse-lasโ when this is on, the global CSE pass gets rid of redundant loads that come right after stores to the same memory location, covering both partial and full redundancies ๐งผ Not enabled at any optimization level.-fgcse-after-reloadโ when this is on, a redundant load elimination pass runs after reload ๐งน Its whole purpose is cleaning up redundant spilling. Enabled by-fprofile-useand-fauto-profile.-faggressive-loop-optimizationsโ the loop optimizer uses language rules to figure out bounds for how many times a loop runs ๐ง It assumes the loop code doesn't trigger undefined behavior, like signed integer overflows or out-of-bounds array accesses. Those bounds guide loop unrolling, peeling, and loop exit test optimizations. This option is enabled by default โจ-funconstrained-commonsโ this tells the compiler that variables declared in common blocks (like in Fortran) might later get overridden with longer trailing arrays ๐ธ That stops certain optimizations that depend on knowing the array bounds.-fcrossjumpingโ performs the cross-jumping transformation ๐ It unifies equivalent code and saves code size. The result might or might not run faster than without it. Enabled at levels-O2,-O3,-Os.-fauto-inc-decโ combines increments or decrements of addresses with memory accesses ๐ This pass is always skipped on architectures that don't have instructions to support it. Enabled by default at-Oand higher on architectures that do support it.-fdceโ performs dead code elimination (DCE) on RTL ๐๏ธ Enabled by default at-Oand higher.-fdseโ performs dead store elimination (DSE) on RTL ๐ Enabled by default at-Oand higher.-fif-conversionโ attempts to transform conditional jumps into branch-less equivalents ๐ฆ This includes conditional moves, min, max, set flags, and abs instructions, plus some tricks you can do with standard arithmetic. Whether conditional execution gets used on chips that support it is controlled by-fif-conversion2. Enabled at levels-O,-O2,-O3,-Os, but not with-Og.-fif-conversion2โ uses conditional execution (where available) to transform conditional jumps into branch-less equivalents ๐ซถ Enabled at levels-O,-O2,-O3,-Os, but not with-Og.-fdeclone-ctor-dtorโ okay so the C++ ABI wants multiple entry points for constructors and destructors: one for a base subobject, one for a complete object, and one for a virtual destructor that callsoperator deleteafterwards ๐ง For a hierarchy with virtual bases, the base and complete variants are clones, which means two copies of the function. With this option, those two variants become thunks that call a common implementation, so there's only one real copy. Enabled by-Os.-fdelete-null-pointer-checksโ this assumes programs can't safely dereference null pointers, and that no code or data lives at address zero ๐ It enables simple constant folding optimizations at all optimization levels. On top of that, other GCC optimization passes use this flag to control global dataflow analyses that eliminate useless null pointer checks. Those analyses assume that a memory access to address zero always traps, so if a pointer gets checked after it's already been dereferenced, it can't be null.
Note however that in some environments this assumption is not true. Use -fno-delete-null-pointer-checks to disable this optimization for programs that depend on that behavior ๐ญ
This option is enabled by default on most targets. On Nios II ELF, it defaults to off. On AVR, CR16, and MSP430, this option is completely disabled. The passes that use the dataflow information are enabled independently at different optimization levels ๐
-fdevirtualizeโ attempts to convert calls to virtual functions into direct calls ๐ This happens both within a procedure and interprocedurally, as part of indirect inlining (-findirect-inlining) and interprocedural constant propagation (-fipa-cp). Enabled at levels-O2,-O3,-Os.-fdevirtualize-speculativelyโ attempts to convert calls to virtual functions into speculative direct calls ๐ฎ Using analysis of the type inheritance graph, it figures out the set of likely targets for a given call. If that set is small, preferably of size 1, the call becomes a conditional that picks between a direct call and an indirect call. Speculative calls enable more optimizations, like inlining. If they seem useless after further optimization, they get converted back into their original form.-fdevirtualize-at-ltransโ streams the extra information needed for aggressive devirtualization when the link-time optimizer runs in local transformation mode ๐ฆ This enables more devirtualization, but it significantly increases the size of the streamed data, so it's disabled by default.-fexpensive-optimizationsโ performs a bunch of minor optimizations that are relatively expensive ๐ธ Enabled at levels-O2,-O3,-Os.-freeโ attempts to remove redundant extension instructions ๐งฝ This is especially helpful for the x86-64 architecture, which implicitly zero-extends 64-bit registers after writing to their lower 32-bit half. Enabled for Alpha, AArch64, and x86 at levels-O2,-O3,-Os.-fno-lifetime-dseโ in C++, an object's value is only affected by changes within its lifetime ๐ฆ When the constructor begins, the object has an indeterminate value, and any changes made during its lifetime are dead once the object is destroyed. Normally dead store elimination takes advantage of this. But if your code relies on the object's storage value persisting beyond its lifetime, you can use this flag to disable that optimization. If you want to keep stores made before the constructor starts (say, because youroperator newclears the object storage) but still treat the object as dead after the destructor, you can use-flifetime-dse=1. The default behavior can be explicitly selected with-flifetime-dse=2.-flifetime-dse=0is equivalent to-fno-lifetime-dse๐-flive-range-shrinkageโ attempts to decrease register pressure through register live range shrinkage ๐ท This is helpful for fast processors with small or moderate-sized register sets.-fira-algorithm=algorithmโ ๐ Pick the coloring algorithm the integrated register allocator uses.algorithmcan bepriority, which is Chow's priority coloring, orCB, which is Chaitin-Briggs coloring. Chaitin-Briggs isn't implemented for every architecture, but on the targets that do support it, it's the default because it generates better code ๐ฅ-fira-region=regionโ ๐บ๏ธ Choose which regions the integrated register allocator uses. Theregionargument should be one of these:allโ Treat all loops as register allocation regions. This can give the best results on machines with a small and/or irregular register set ๐mixedโ Treat all loops except loops with small register pressure as the regions. This is usually the best vibe for most cases and most architectures, and it's on by default when you compile with optimization for speed (-O,-O2, ...) โจoneโ Treat all functions as a single region. This usually gives the smallest code size and is on by default for-Osor-O0๐ฆ
-fira-hoist-pressureโ ๐ง Use IRA to evaluate register pressure in the code hoisting pass when deciding whether to hoist expressions. This usually results in smaller code, but it can slow the compiler down ๐ข This option is enabled at level-Osfor all targets.-fira-loop-pressureโ ๐ Use IRA to evaluate register pressure in loops when deciding whether to move loop invariants. This usually generates faster and smaller code on machines with large register files (>= 32registers), but it can slow the compiler down ๐ข This option is enabled at level-O3for some targets.-fno-ira-share-save-slotsโ ๐ซ Turn off sharing of stack slots used for saving call-used hard registers that live through a call. Each hard register gets its own stack slot, so function stack frames end up larger ๐ฆ-fno-ira-share-spill-slotsโ ๐ซ Turn off sharing of stack slots allocated for pseudo-registers. Every pseudo-register that doesn't get a hard register gets its own stack slot, so function stack frames end up larger ๐ฆ-flra-rematโ โป๏ธ Enable CFG-sensitive rematerialization in LRA. Instead of loading the values of spilled pseudos, LRA tries to rematerialize (recalculate) them when that's profitable. Enabled at levels-O2,-O3,-Osโจ-fdelayed-branchโ โฑ๏ธ If the target machine supports it, the compiler tries to reorder instructions so they fill the instruction slots available after delayed branch instructions. Enabled at levels-O,-O2,-O3,-Os, but not at-Og๐-fschedule-insnsโ ๐ If the target machine supports it, the compiler tries to reorder instructions to get rid of execution stalls caused by data that isn't ready yet. This is a lifesaver for machines with slow floating point or memory load instructions, because other instructions can get issued while the load or floating-point result is still on its way. Enabled at levels-O2,-O3๐ธ-fschedule-insns2โ ๐ Similar to-fschedule-insns, but it asks for an extra round of instruction scheduling after register allocation is done. This is especially useful on machines with a relatively small number of registers where memory load instructions take more than one cycle. Enabled at levels-O2,-O3,-Os๐-fno-sched-interblockโ ๐ง Turn off instruction scheduling across basic blocks. This is normally on when scheduling happens before register allocation, i.e. with-fschedule-insnsor at-O2or higher.-fno-sched-specโ ๐ง Turn off speculative motion of non-load instructions. This is normally on when scheduling happens before register allocation, i.e. with-fschedule-insnsor at-O2or higher.-fsched-pressureโ ๐ Enable register pressure sensitive instruction scheduling before register allocation. This only makes sense when scheduling before register allocation is enabled, i.e. with-fschedule-insnsor at-O2or higher. Using it can improve the generated code and shrink its size by stopping register pressure from climbing above the number of available hard registers, which would otherwise lead to spills during register allocation ๐ซถ-fsched-spec-loadโ ๐ฎ Allow speculative motion of some load instructions. This only makes sense when scheduling before register allocation, i.e. with-fschedule-insnsor at-O2or higher.-fsched-spec-load-dangerousโ ๐ฌ Allow speculative motion of more load instructions. This only makes sense when scheduling before register allocation, i.e. with-fschedule-insnsor at-O2or higher.-fsched-stalled-insns,-fsched-stalled-insns=nโ ๐ง Decide how many instructions (if any) can be moved early from the queue of stalled instructions into the ready list during the second scheduling pass.-fno-sched-stalled-insnsmeans no instructions get moved early.-fsched-stalled-insns=0means there's no limit on how many queued instructions can be moved early.-fsched-stalled-insnswithout a value is the same as-fsched-stalled-insns=1.
-fsched-stalled-insns-dep,-fsched-stalled-insns-dep=nโ ๐ Decide how many instruction groups (cycles) get checked for a dependency on a stalled instruction that's a candidate for early removal from the queue. This only has an effect during the second scheduling pass, and only if-fsched-stalled-insnsis used.-fno-sched-stalled-insns-depis the same as-fsched-stalled-insns-dep=0.-fsched-stalled-insns-depwithout a value is the same as-fsched-stalled-insns-dep=1.
-fsched2-use-superblocksโ ๐ฆธ When scheduling after register allocation, use superblock scheduling. This allows motion across basic block boundaries, which can result in faster schedules.
โ ๏ธ This option is experimental! Not all machine descriptions used by GCC model the CPU closely enough to avoid unreliable results from the algorithm, so be careful.
This only makes sense when scheduling after register allocation, i.e. with -fschedule-insns2 or at -O2 or higher.
-fsched-group-heuristicโ ๐ฏ Enable the group heuristic in the scheduler. This one favors the instruction that belongs to a schedule group. It's on by default whenever scheduling is enabled, i.e. with-fschedule-insnsor-fschedule-insns2or at-O2or higher.-fsched-critical-path-heuristicโ ๐ฃ๏ธ Enable the critical-path heuristic in the scheduler. This one favors instructions on the critical path. It's on by default whenever scheduling is enabled, i.e. with-fschedule-insnsor-fschedule-insns2or at-O2or higher.-fsched-spec-insn-heuristicโ ๐ฒ Enable the speculative instruction heuristic in the scheduler. This one favors speculative instructions with greater dependency weakness. It's on by default whenever scheduling is enabled, i.e. with-fschedule-insnsor-fschedule-insns2or at-O2or higher.-fsched-rank-heuristicโ ๐ Enable the rank heuristic in the scheduler. This one favors instructions in a basic block with greater size or frequency. It's on by default whenever scheduling is enabled, i.e. with-fschedule-insnsor-fschedule-insns2or at-O2or higher.-fsched-last-insn-heuristicโ ๐ซ Enable the last-instruction heuristic in the scheduler. This one favors the instruction that depends less on the last instruction scheduled. It's on by default whenever scheduling is enabled, i.e. with-fschedule-insnsor-fschedule-insns2or at-O2or higher.-fsched-dep-count-heuristicโ ๐งฎ Enable the dependent-count heuristic in the scheduler. This one favors the instruction that has more instructions depending on it. It's on by default whenever scheduling is enabled, i.e. with-fschedule-insnsor-fschedule-insns2or at-O2or higher.-freschedule-modulo-scheduled-loopsโ ๐ Modulo scheduling happens before traditional scheduling. If a loop has been modulo scheduled, later scheduling passes may change its schedule. Use this option to control that behavior ๐๏ธ-fselective-schedulingโ ๐ฏ Schedule instructions using the selective scheduling algorithm. Selective scheduling runs instead of the first scheduler pass.-fselective-scheduling2โ ๐ฏ Schedule instructions using the selective scheduling algorithm. Selective scheduling runs instead of the second scheduler pass.-fsel-sched-pipeliningโ ๐ฐ Enable software pipelining of innermost loops during selective scheduling. This option does nothing unless-fselective-schedulingor-fselective-scheduling2is turned on.-fsel-sched-pipelining-outer-loopsโ ๐ช When pipelining loops during selective scheduling, also pipeline the outer loops. This option does nothing unless-fsel-sched-pipeliningis turned on.-fsemantic-interpositionโ ๐ต๏ธ Some object formats, like ELF, let the dynamic linker interpose symbols. That means that for symbols exported from the DSO, the compiler can't do interprocedural propagation, inlining, and other optimizations, because the function or variable might get swapped out for something else. This is super useful for things like rewriting memory allocation functions with a debugging implementation, but it's expensive in terms of code quality ๐ธ With-fno-semantic-interposition, the compiler assumes that if interposition happens for functions, the overwriting function will have precisely the same semantics (and side effects). Similarly, if interposition happens for variables, the constructor of the variable will be the same. This flag has no effect on functions explicitly declaredinline(where interposition is never allowed to change semantics) or on symbols explicitly declaredweak.-fshrink-wrapโ ๐ Emit function prologues only before the parts of the function that need them, rather than at the top of the function. This flag is enabled by default at-Oand higher โจ-fshrink-wrap-separateโ โ๏ธ Shrink-wrap the parts of the prologue and epilogue separately, so each part only runs when it's needed. This option is on by default, but it has no effect unless-fshrink-wrapis also turned on and the target supports this ๐-fcaller-savesโ okay so this one is lowkey genius ๐ It lets GCC park values in registers that function calls would normally wreck, then sneaks in extra instructions to save and restore those registers around each call ๐ซถ It only does this when it seems to actually produce better code, so it's never doing it for no reason ๐- This is always turned on by default on certain machines, usually the ones with no call-preserved registers to use instead โจ
- Enabled at levels
-O2,-O3,-Os๐ฅ
-fcombine-stack-adjustmentsโ the way this one tracks every push and pop, plus all the stack memory references, and then tries to squish them together is so iconic ๐ง Enabled by default at-O1and higher ๐ธ-fipa-raโ bestie, this is main character energy ๐ It lets the compiler use caller-save registers for allocation when none of the called functions are using them, so there's no need to save and restore them around calls ๐ฆ This only works if the called functions are part of the same compilation unit as the current function and get compiled before it ๐ซถ- Enabled at levels
-O2,-O3,-Os, but it gets switched off if the generated code will be instrumented for profiling (-p, or-pg) or if the callee's register usage can't be known exactly, which happens on targets that don't expose prologues and epilogues in RTL ๐
- Enabled at levels
-fconserve-stackโ this one is all about keeping the stack tiny, even if the program ends up a little slower ๐ The compiler tries to use less stack space no matter what, and turning it on implies setting thelarge-stack-frameparameter to100and thelarge-stack-frame-growthparameter to400๐-ftree-reassocโ performs reassociation on trees, and it's on by default at-Oand higher โจ-fcode-hoistingโ okay this is so satisfying ๐ Code hoisting tries to move the evaluation of expressions that run on all paths to the function exit as early as possible ๐ง It's especially useful as a code size optimization, but it often helps code speed too ๐ Enabled by default at-O2and higher ๐-ftree-preโ performs partial redundancy elimination (PRE) on trees ๐ธ Enabled by default at-O2and-O3โจ-ftree-partial-preโ makes partial redundancy elimination (PRE) more aggressive ๐ญ Enabled by default at-O3๐ฅ-ftree-forwpropโ performs forward propagation on trees ๐ฆ Enabled by default at-Oand higher ๐-ftree-freโ performs full redundancy elimination (FRE) on trees ๐ซถ The tea is that FRE only considers expressions computed on all paths leading to the redundant computation, which makes it faster than PRE, though it exposes fewer redundancies ๐ต Enabled by default at-Oand higher ๐-ftree-phipropโ performs hoisting of loads from conditional pointers on trees ๐ง This pass is enabled by default at-Oand higher โจ-fhoist-adjacent-loadsโ this one speculatively hoists loads from both branches of an if-then-else, as long as the loads come from adjacent locations in the same structure and the target architecture has a conditional move instruction ๐ธ Enabled by default at-O2and higher ๐-ftree-copy-propโ performs copy propagation on trees, and this pass gets rid of unnecessary copy operations ๐ซถ Enabled by default at-Oand higher ๐ฅ-fipa-pure-constโ discovers which functions are pure or constant ๐ฎ Enabled by default at-Oand higher ๐-fipa-referenceโ discovers which static variables don't escape the compilation unit ๐ฆ Enabled by default at-Oand higher ๐-fipa-reference-addressableโ discovers read-only, write-only, and non-addressable static variables ๐ Enabled by default at-Oand higher โจ-fipa-stack-alignmentโ reduces stack alignment on call sites when possible ๐ธ Enabled by default ๐-fipa-ptaโ performs interprocedural pointer analysis along with interprocedural modification and reference analysis ๐ญ Heads up, bestie: this can cause excessive memory and compile-time usage on large compilation units ๐- It is not enabled by default at any optimization level ๐
-fipa-profileโ performs interprocedural profile propagation ๐ง Functions called only from cold functions get marked as cold, and functions that run once (like"cold","noreturn", static constructors, or destructors) get identified too ๐ธ Then the cold functions and the parts of functions with no loops that run once get optimized for size ๐ซถ Enabled by default at-Oand higher ๐-fipa-cpโ performs interprocedural constant propagation ๐ฅ This one analyzes the program to figure out when values passed to functions are constants, then optimizes accordingly ๐ฆ It can substantially increase performance if your application has constants passed to functions ๐ Enabled by default at-O2,-Os, and-O3๐ It's also enabled by-fprofile-useand-fauto-profileโจ-fipa-cp-cloneโ performs function cloning to make interprocedural constant propagation stronger ๐ง When enabled, interprocedural constant propagation clones functions when an externally visible function can be called with constant arguments ๐ Heads up, though: because this can create multiple copies of functions, it may significantly increase code size (see--param ipa-cp-unit-growth=value) ๐ Enabled by default at-O3๐ซถ It's also enabled by-fprofile-useand-fauto-profile๐-fipa-bit-cpโ when enabled, performs interprocedural bitwise constant propagation ๐ธ Enabled by default at-O2and by-fprofile-useand-fauto-profile๐ It requires that-fipa-cpis enabled ๐ซถ-fipa-vrpโ when enabled, performs interprocedural propagation of value ranges ๐ฆ Enabled by default at-O2๐ฅ It requires that-fipa-cpis enabled โจ-fipa-icfโ performs Identical Code Folding for functions and read-only variables ๐ This shrinks code size, but it may disturb unwind stacks by replacing a function with an equivalent one that has a different name ๐ญ It works more effectively with link-time optimization enabled ๐ง- Although the behavior is similar to the Gold Linker's ICF optimization, GCC ICF works on different levels, so the optimizations aren't the same. There are equivalences that only GCC finds and equivalences that only Gold finds ๐ค
- Enabled by default at
-O2and-Os๐
-flive-patching=levelโ this is the live-patching glow-up ๐ฆ It controls GCC's optimizations so the output is suitable for live-patching ๐ซถ- If the compiler's optimization uses a function's body, or information pulled from that body, to optimize or change another function, the latter is called an impacted function of the former ๐ง If a function gets patched, its impacted functions should be patched too ๐ฅ
- The impacted functions are determined by the compiler's interprocedural optimizations ๐ธ For example, a caller is impacted when a function gets inlined into it, when a function gets cloned and its caller is changed to call that new clone, or when a function's pureness or constness info gets extracted to optimize its direct or indirect callers, and so on ๐
- Usually, the more IPA optimizations are enabled, the more impacted functions each function has ๐ To control how many impacted functions there are and to make the list easier to compute, IPA optimizations can be partially enabled at two different levels ๐
- The
levelargument should be one of the following:inline-cloneโ only enables inlining and cloning optimizations, which include inlining, cloning, interprocedural scalar replacement of aggregates, and partial inlining ๐ซถ As a result, when patching a function, all of its callers and its clones' callers are impacted, so they need to be patched as well ๐-flive-patching=inline-clonedisables these optimization flags:-fwhole-program-fipa-pta-fipa-reference-fipa-ra-fipa-icf-fipa-icf-functions-fipa-icf-variables-fipa-bit-cp-fipa-vrp-fipa-pure-const-fipa-reference-addressable-fipa-stack-alignment๐
inline-only-staticโ only enables inlining of static functions ๐ง As a result, when patching a static function, all of its callers are impacted and need to be patched as well ๐ธ- On top of everything
-flive-patching=inline-clonedisables,-flive-patching=inline-only-staticalso disables these extra flags:-fipa-cp-clone-fipa-sra-fpartial-inlining-fipa-cp๐
- On top of everything
- When
-flive-patchingis specified without any value, the default value isinline-cloneโจ - This flag is disabled by default ๐ญ
- Note that
-flive-patchingis not supported with link-time optimization (-flto) ๐ซ
-fisolate-erroneous-paths-dereferenceโ detects paths that trigger erroneous or undefined behavior from dereferencing a null pointer ๐ฅ It isolates those paths from the main control flow and turns the statement with the erroneous or undefined behavior into a trap ๐ Enabled by default at-O2and higher, and it depends on-fdelete-null-pointer-checksalso being enabled ๐ซถ-fisolate-erroneous-paths-attributeโ detects paths that trigger erroneous or undefined behavior because a null value is used in a way forbidden by a"returns_nonnull"or"nonnull"attribute ๐ญ It isolates those paths from the main control flow and turns the statement into a trap ๐ง This is not currently enabled, but it may be enabled by-O2in the future ๐-ftree-sinkโ performs forward store motion on trees ๐ฆ Enabled by default at-Oand higher ๐-ftree-bit-ccpโ performs sparse conditional bit constant propagation on trees and propagates pointer alignment information ๐ This pass only operates on local scalar variables and is enabled by default at-O1and higher, except for-Ogโจ It requires that-ftree-ccpis enabled ๐ซถ-ftree-ccpโ performs sparse conditional constant propagation (CCP) on trees ๐ธ This pass only operates on local scalar variables and is enabled by default at-Oand higher ๐-fssa-backpropโ propagates information about uses of a value up the definition chain to simplify the definitions ๐ง For example, this pass strips sign operations if the sign of a value never matters ๐ฅ The flag is enabled by default at-Oand higher ๐-fssa-phioptโ okay so this one does pattern matching on SSA PHI nodes to tidy up conditional code โจ It's on by default at-O1and higher, except for-Og๐-ftree-switch-conversionโ bestie, this turns simple initializations inside aswitchinto initializations from a scalar array ๐ธ It's on by default at-O2and higher ๐ซถ-ftree-tail-mergeโ this one hunts for identical code sequences ๐ฆ When it finds a match, it swaps one copy out for a jump to the other. It's known as tail merging or cross jumping, and I'm obsessed ๐ญ It's on by default at-O2and higher. The compile time for this pass can be capped with themax-tail-merge-comparisonsparameter and themax-tail-merge-iterationsparameter ๐ง-ftree-dceโ dead code elimination (DCE) on trees, iconic ๐ It's on by default at-Oand higher ๐ฅ-ftree-builtin-call-dceโ conditional DCE for calls to built-in functions that may set"errno"but are otherwise free of side effects ๐ It's on at-O2and higher, unless-Osis also specified ๐-ffinite-loopsโ we assume a loop with an exit will eventually take the exit and won't loop forever ๐ That lets the compiler remove loops with no side effects, since endless looping just isn't considered. It's enabled by default at-O2for C++ with-std=c++11or higher โจ-ftree-dominator-optsโ a bunch of simple scalar cleanups based on a dominator tree traversal ๐งน That includes constant/copy propagation, redundancy elimination, range propagation, and expression simplification. It also does jump threading, which reduces jumps to jumps ๐ฆ On at-Oand higher.-ftree-dseโ dead store elimination (DSE) on trees ๐ A dead store is a store into a memory location that gets overwritten later by another store, with no loads in between. In that case the earlier store can be deleted ๐ On at-Oand higher.-ftree-chโ loop header copying on trees ๐ This is so helpful because it boosts code motion optimizations and saves one jump โจ It's on at-Oand higher, but not for-Os, since it usually increases code size ๐ญ-ftree-loop-optimizeโ loop optimizations on trees ๐ On at-Oand higher.-ftree-loop-linear,-floop-strip-mine,-floop-blockโ loop nest optimizations, same as-floop-nest-optimize๐ To use this transformation, GCC has to be configured with--with-islso the Graphite loop transformation infrastructure is enabled ๐ง-fgraphite-identityโ enables the identity transformation for graphite ๐ช For every SCoP we generate the polyhedral representation and transform it back to gimple. This lets you check the costs or benefits of theGIMPLE -> GRAPHITE -> GIMPLEtransformation ๐ The isl code generator also does some minimal optimizations, like index splitting and dead code elimination in loops โจ-floop-nest-optimizeโ turns on the isl based loop nest optimizer ๐ง It's a generic loop nest optimizer based on the Pluto optimization algorithms, and it calculates a loop structure optimized for data-locality and parallelism ๐ This option is experimental, so be careful, bestie ๐-floop-parallelize-allโ uses Graphite data dependence analysis to find loops that can be parallelized ๐งต It parallelizes all the loops that can be analyzed as not containing loop carried dependences, without checking whether parallelizing them is actually profitable ๐ฌ-ftree-coalesce-varsโ when transforming the program out of SSA form, it tries to reduce copying by coalescing versions of different user-defined variables, not just compiler temporaries ๐ซง This can severely limit your ability to debug an optimized program compiled with-fno-var-tracking-assignments๐ In the negated form,-fno-tree-coalesce-vars, the flag prevents SSA coalescing of user variables. It's enabled by default if optimization is enabled, and it does very little otherwise ๐ธ-ftree-loop-if-convertโ tries to transform conditional jumps in the innermost loops into branch-less equivalents ๐ The goal is to remove control flow from the innermost loops so the vectorization pass can handle them better ๐ It's enabled by default if vectorization is enabled.-ftree-loop-distributionโ loop distribution, and it's giving performance ๐ It can improve cache performance on big loop bodies and lets further loop optimizations, like parallelization or vectorization, take place ๐ For example, this Fortran loop:
DO I = 1, N
A(I) = B(I) + C
D(I) = E(I) * F
ENDDO
gets transformed into:
DO I = 1, N
A(I) = B(I) + C
ENDDO
DO I = 1, N
D(I) = E(I) * F
ENDDO
This flag is enabled by default at -O3. It's also enabled by -fprofile-use and -fauto-profile ๐ซถ
-ftree-loop-distribute-patternsโ loop distribution of patterns that can be code generated as calls to a library ๐ It's enabled by default at-O2and higher, and by-fprofile-useand-fauto-profileโจ
This pass distributes the initialization loops and generates a call to memset zero ๐งธ For example, this loop:
DO I = 1, N
A(I) = 0
B(I) = A(I) + I
ENDDO
is transformed to:
DO I = 1, N
A(I) = 0
ENDDO
DO I = 1, N
B(I) = A(I) + I
ENDDO
and the initialization loop is transformed into a call to memset zero. This flag is enabled by default at -O3. It's also enabled by -fprofile-use and -fauto-profile ๐
-floop-interchangeโ loop interchange outside of graphite ๐ It can improve cache performance on loop nests and lets further loop optimizations, like vectorization, take place. For example, this C loop:
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
c[i][j] = c[i][j] + a[i][k]*b[k][j];
is transformed to:
for (int i = 0; i < N; i++)
for (int k = 0; k < N; k++)
for (int j = 0; j < N; j++)
c[i][j] = c[i][j] + a[i][k]*b[k][j];
This flag is enabled by default at -O3. It's also enabled by -fprofile-use and -fauto-profile ๐
-floop-unroll-and-jamโ applies unroll and jam transformations on feasible loops ๐ซ In a loop nest, this unrolls the outer loop by some factor and fuses the resulting multiple inner loops ๐ซ It's enabled by default at-O3, and also by-fprofile-useand-fauto-profileโญ-ftree-loop-imโ loop invariant motion on trees ๐ This pass only moves invariants that are hard to handle at the RTL level, like function calls or operations that expand to nontrivial sequences of insns. With-funswitch-loops, it also moves operands of invariant conditions out of the loop, so that trivial invariantness analysis can be used in loop unswitching ๐ง The pass also includes store motion ๐ซง-ftree-loop-ivcanonโ creates a canonical counter for the number of iterations in loops where figuring that out needs complicated analysis ๐ข Later optimizations may then determine the number easily. It's especially useful in connection with unrolling ๐-ftree-scev-cpropโ performs final value replacement ๐ If a variable is modified in a loop in such a way that its value on exit can be determined using only its initial value and the number of loop iterations, uses of the final value get replaced by that computation, provided it's sufficiently cheap ๐ This reduces data dependencies and may allow further simplifications. It's enabled by default at-Oand higher.-fivoptsโ induction variable optimizations on trees, including strength reduction, induction variable merging, and induction variable elimination ๐งฎ-ftree-parallelize-loops=nโ parallelizes loops by splitting their iteration space to run across n threads ๐งต This is only possible for loops whose iterations are independent and can be arbitrarily reordered. The optimization is only profitable on multiprocessor machines, and only for CPU-intensive loops rather than loops constrained by, e.g., memory bandwidth. This option implies-pthread, so it's only supported on targets that have support for-pthread๐-ftree-ptaโ function-local points-to analysis on trees ๐ฏ It's enabled by default at-O1and higher, except for-Og.-ftree-sraโ scalar replacement of aggregates ๐ช It replaces structure references with scalars so that structures don't get committed to memory too early. It's enabled by default at-O1and higher, except for-Og๐-fstore-mergingโ merges narrow stores to consecutive memory addresses ๐ฆ Contiguous stores of immediate values narrower than a word get merged into fewer, wider stores to cut down on the number of instructions. It's enabled by default at-O2and higher, as well as-Os๐ธ-ftree-terโ temporary expression replacement during theSSA->normalphase ๐ Single use/single def temporaries get replaced at their use location with their defining expression. This results in non-GIMPLE code, but it gives the expanders much more complex trees to work on, resulting in better RTL generation ๐ It's enabled by default at-Oand higher.-ftree-slsrโ straight-line strength reduction on trees ๐ It recognizes related expressions involving multiplications and replaces them with less expensive calculations when possible. It's enabled by default at-Oand higher ๐-ftree-vectorizeโ vectorization on trees ๐ This flag enables-ftree-loop-vectorizeand-ftree-slp-vectorizeif they aren't explicitly specified.-ftree-loop-vectorizeโ loop vectorization on trees ๐ It's enabled by default at-O3, and by-ftree-vectorize,-fprofile-use, and-fauto-profile๐ซถ
okay bestie, so the next batch is all about the vibe checks for loops, paths, and blocks, and it's giving optimizer main character ๐ โจ
-ftree-slp-vectorizeโ ๐ฆ basic block vectorization on trees, lowkey on by default at-O3, and also turned on by-ftree-vectorize,-fprofile-use, and-fauto-profile. no cap, it's a whole vibe ๐-fvect-cost-model=modelโ ๐ this one changes how the compiler decides whether vectorizing is worth it.modelhas to beunlimited,dynamic, orcheap. withunlimited, the vectorized path is just assumed to be profitable (bold choice ๐). withdynamic, a runtime check guards the vectorized path so it only kicks in for iteration counts that will probably run faster than the original scalar loop ๐ซถ.cheapis the picky one: it skips vectorizing loops where that would be too expensive, like when it needs runtime checks for data dependence or alignment, but otherwise it's the same asdynamic๐ธ. the default depends on your other optimization flags, and it'll be eitherdynamicorcheapโจ-fsimd-cost-model=modelโ ๐ง same energy, but only for loops marked with the OpenMPsimddirective.modelcan beunlimited,dynamic, orcheap, and they all mean exactly what they meant in-fvect-cost-model๐ซถ. by default, this just borrows whatever cost model-fvect-cost-modelis using ๐-ftree-vrpโ ๐ performs Value Range Propagation on trees. it's kinda like constant propagation, except instead of tracking single values, it tracks whole ranges of values ๐ญ. that lets the optimizers delete stuff like array bound checks and null pointer checks when they're not needed. enabled by default at-O2and higher ๐ฅ. just a heads up: null pointer check elimination only happens if-fdelete-null-pointer-checksis turned on ๐-fsplit-pathsโ ๐ splits paths that lead to loop backedges, which can help dead code elimination and common subexpression elimination glow up โจ. enabled by default at-O3and above ๐-fsplit-ivs-in-unrollerโ ๐ฆ when a loop gets unrolled, this lets the values of induction variables in later iterations be worked out from the value in the first iteration. the result is that long dependency chains get broken up, which makes the scheduling passes way more efficient ๐ฅ. enabled by default ๐
A combination of -fweb and CSE is often enough to get the same effect, ngl ๐. but it's not reliable when the loop body is more complicated than one basic block, and on some architectures it doesn't work at all because of restrictions in the CSE pass ๐ญ.
-fvariable-expansion-in-unrollerโ ๐ when a loop is unrolled, the compiler makes multiple copies of some local variables, which can end up giving you better code ๐ซถ. this is enabled by default for PowerPC targets, but disabled by default everywhere else ๐ธ.-fpartial-inliningโ ๐ inlines parts of functions. this only does anything if inlining is already turned on by-finline-functionsor-finline-small-functionsโจ. enabled at levels-O2,-O3, and-Os๐.-fpredictive-commoningโ ๐ง performs predictive commoning, which basically means reusing computations (especially memory loads and stores) that were already done in previous loop iterations ๐ . enabled at level-O3, and also turned on by-fprofile-useand-fauto-profile๐ฅ.-fprefetch-loop-arraysโ ๐ฆ if the target machine supports it, this generates instructions to prefetch memory, which can speed up loops that chew through large arrays ๐. just know that the results can be better or worse, and they really depend on how the loops are structured in your source code ๐ญ. disabled at level-Os๐.
-fno-printf-return-valueโ โจ stops the compiler from swapping in constants for the known return values of formatted output functions like"sprintf","snprintf","vsprintf", and"vsnprintf"(but not"printf"of"fprintf") ๐ธ. normally this lets GCC optimize or even delete branches based on those known return values, as long as the arguments are constant or known to be in a range where the exact return value can be figured out ๐ง. for example, with-fprintf-return-valuein effect, both the branch and the body of theifstatement (but not the call to"snprint") can be optimized away wheniis a 32-bit or smaller integer, because the return value is guaranteed to be at most 8 ๐.
char buf[9];
if (snprintf (buf, "%08x", i) >= sizeof buf)
...
The -fprintf-return-value option depends on other optimizations and gives the best results with -O2 and above ๐ฅ. it works together with -Wformat-overflow and -Wformat-truncation ๐ซถ. -fprintf-return-value is enabled by default ๐.
-fno-peephole,-fno-peephole2โ ๐ disables any machine-specific peephole optimizations ๐ . the difference between the two is how they're implemented inside the compiler: some targets use one, some use the other, and a few use both ๐.-fpeepholeis enabled by default ๐, and-fpeephole2is enabled at levels-O2,-O3, and-Osโจ.-fno-guess-branch-probabilityโ ๐ง tells the compiler to stop guessing branch probabilities with heuristics ๐. normally, when profiling feedback (-fprofile-arcs) doesn't provide the probabilities, GCC uses heuristics based on the control flow graph to guess them ๐ฆ. if some branch probabilities are set by__builtin_expect, the heuristics still guess the rest of the control flow graph, and they take the__builtin_expectinfo into account ๐ซถ. the way the heuristics and__builtin_expectinteract can get super complicated, so sometimes it helps to turn the heuristics off so the effects of__builtin_expectare easier to understand ๐ญ. you can also set the expected probability of an expression with the__builtin_expect_with_probabilitybuilt-in function ๐. the default is-fguess-branch-probabilityat levels-O,-O2,-O3, and-Os๐.-freorder-blocksโ ๐ reorders basic blocks in the compiled function to cut down on taken branches and improve code locality ๐ธ. enabled at levels-O,-O2,-O3, and-Osโจ.-freorder-blocks-algorithm=algorithmโ ๐ง picks the algorithm used for basic block reordering.algorithmcan besimple, which doesn't increase code size (except sometimes through secondary effects like alignment), orstc, the "software trace cache" algorithm ๐ .stctries to group all the often-executed code together, which minimizes the number of branches executed by making extra copies of code ๐ฅ. the default issimpleat levels-Oand-Os, andstcat levels-O2and-O3๐.-freorder-blocks-and-partitionโ ๐ฆ on top of reordering basic blocks (to reduce taken branches), this splits hot and cold basic blocks into separate sections of the assembly and.ofiles, which helps paging and cache locality ๐. this gets automatically turned off when there's exception handling or unwind tables (on targets using setjump/longjump or a target-specific scheme), for linkonce sections, for functions with a user-defined section attribute, and on any architecture that doesn't support named sections ๐ญ. when-fsplit-stackis used, this option isn't enabled by default (to avoid linker errors), but you can still turn it on explicitly if you have a working linker ๐. enabled for x86 at levels-O2,-O3, and-Os๐.-freorder-functionsโ ๐ reorders functions in the object file to improve code locality โจ. it does this with special subsections:.text.hotfor the most frequently executed functions and.text.unlikelyfor the unlikely ones ๐ซถ. the reordering is done by the linker, so the object file format has to support named sections, and the linker has to place them sensibly ๐ง. this option does nothing unless you either provide profile feedback (see-fprofile-arcs) or manually annotate functions withhotorcoldattributes ๐. enabled at levels-O2,-O3, and-Os๐ .-fstrict-aliasingโ ๐ lets the compiler assume the strictest aliasing rules that apply to the language being compiled ๐ฅ. for C (and C++), that turns on optimizations based on the type of expressions ๐. basically, an object of one type is assumed to never live at the same address as an object of a different type, unless the types are almost the same ๐. for example, anunsigned intcan alias anint, but not avoid*or adouble, and a character type can alias any other type ๐ธ.
Pay special attention to code like this ๐:
union a_union {
int i;
double d;
};
int f() {
union a_union t;
t.d = 3.0;
return t.i;
}
reading from a different union member than the one you wrote to most recently (called "type-punning") is super common ๐. even with -fstrict-aliasing, type-punning is allowed, as long as the memory is accessed through the union type, so the code above works as expected โจ. however, this code might not ๐ญ:
int f() {
union a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
return *ip;
}
similarly, accessing something by taking its address, casting the resulting pointer, and then dereferencing it has undefined behavior, even if the cast uses a union type ๐. for example:
int f() {
double d = 3.0;
return ((union a_union *) &d)->i;
}
the -fstrict-aliasing option is enabled at levels -O2, -O3, and -Os ๐ซถ.
-falign-functions,-falign-functions=n,-falign-functions=n:m,-falign-functions=n:m:n2,-falign-functions=n:m:n2:m2โ ๐ aligns the start of functions to the next power of two that is greater than or equal ton, skipping up tom-1bytes ๐ฆ. this makes sure at least the firstmbytes of the function can be fetched by the CPU without crossing ann-byte alignment boundary ๐. ifmisn't specified, it defaults ton๐ธ.
examples, bc you'll want them ๐ง: -falign-functions=32 aligns functions to the next 32-byte boundary, -falign-functions=24 aligns to the next 32-byte boundary only if that can be done by skipping 23 bytes or less, and -falign-functions=32:7 aligns to the next 32-byte boundary only if that can be done by skipping 6 bytes or less ๐โจ
The second pair of n2:m2 values lets you set a secondary alignment, and honestly it's lowkey genius ๐
. For example, -falign-functions=64:7:32:3 aligns to the next 64-byte boundary if that can be done by skipping 6 bytes or less. Otherwise it aligns to the next 32-byte boundary, but only if that can be done by skipping 2 bytes or less. If m2 isn't specified, it defaults to n2 โจ.
Some assemblers only support this flag when n is a power of two. In that case, n gets rounded up ๐ง.
-fno-align-functionsand-falign-functions=1โ these two are literal twins ๐ฏ. They both mean functions are not aligned at all.
If n is missing or zero, GCC picks a machine-dependent default for you ๐. The biggest n you can pass is 65536.
Enabled at levels -O2, -O3 ๐ฅ.
-flimit-function-alignmentโ this one is the responsible friend ๐ซถ. When it's on, the compiler tries not to overalign functions for no reason. It asks the assembler to align by the amount you set with-falign-functions, but it won't skip more bytes than the size of the function itself. No wasted padding, bestie ๐.-falign-labels,-falign-labels=n,-falign-labels=n:m,-falign-labels=n:m:n2,-falign-labels=n:m:n2:m2โ this aligns all branch targets to a power-of-two boundary ๐ฆ. The parameters work just like they do for-falign-functions.-fno-align-labelsand-falign-labels=1are equivalent and mean labels are not aligned ๐.
If -falign-loops or -falign-jumps are applicable and bigger than this value, their values win instead ๐.
If n isn't specified or is zero, GCC uses a machine-dependent default that is very likely to be 1, which means no alignment at all. The maximum allowed n is 65536.
Enabled at levels -O2, -O3 ๐ธ.
-falign-loops,-falign-loops=n,-falign-loops=n:m,-falign-loops=n:m:n2,-falign-loops=n:m:n2:m2โ this aligns loops to a power-of-two boundary ๐. If the loop runs a ton of times, the padding instructions it adds are totally worth it, since they only run once per loop entry instead of every single iteration โจ.
If -falign-labels is bigger than this value, its value gets used instead.
The parameters are analogous to -falign-functions. -fno-align-loops and -falign-loops=1 are equivalent and mean that loops are not aligned. The maximum allowed n is 65536.
If n isn't specified or is zero, GCC uses a machine-dependent default.
Enabled at levels -O2, -O3 ๐.
-falign-jumps,-falign-jumps=n,-falign-jumps=n:m,-falign-jumps=n:m:n2,-falign-jumps=n:m:n2:m2โ this aligns branch targets to a power-of-two boundary, but only for targets you can reach by jumping ๐ฆ. Since nothing falls through into them, no dummy operations need to run. Nice and efficient ๐ .
If -falign-labels is bigger than this value, its value is used instead.
The parameters are analogous to -falign-functions. -fno-align-jumps and -falign-jumps=1 are equivalent and mean that loops are not aligned (yes, the page says loops, I'm not fixing it, just vibing with it ๐).
If n isn't specified or is zero, GCC uses a machine-dependent default. The maximum allowed n is 65536.
Enabled at levels -O2, -O3 ๐.
-fno-allocation-dceโ this tells GCC to keep unused C++ allocations rather than deleting them during dead code elimination ๐ โโ๏ธ.-fallow-store-data-racesโ this lets the compiler introduce new data races on stores. Spicy, so be careful ๐.
Enabled at level -Ofast ๐ฅ.
-funit-at-a-timeโ this one's kept around just for compatibility reasons ๐ง. It does nothing on its own, but-fno-unit-at-a-timeimplies-fno-toplevel-reorderand-fno-section-anchors.
Enabled by default โจ.
-fno-toplevel-reorderโ this stops GCC from shuffling top-level functions, variables, andasmstatements around. Everything gets output in the exact order it shows up in the input file ๐. With this on, unreferenced static variables are not removed. It's mainly there so existing code that relies on a particular ordering keeps working. For new code, use attributes whenever you can ๐.
-ftoplevel-reorder is the default at -O1 and higher, and also at -O0 if -fsection-anchors is explicitly requested. Also, -fno-toplevel-reorder implies -fno-section-anchors ๐ง.
-fwebโ this constructs webs (the way they're commonly used for register allocation) and gives each web its own pseudo register ๐ธ๏ธ. The register allocation pass can then work on pseudos directly, and it also strengthens passes like CSE, the loop optimizer, and the trivial dead code remover. The tradeoff? It can make debugging basically impossible, since variables stop living in a "home register" ๐ญ.
Enabled by default with -funroll-loops ๐.
-fwhole-programโ this assumes the current compilation unit is the whole program being compiled ๐. All public functions and variables, exceptmainand anything merged by the attributeexternally_visible, become static functions. That lets the interprocedural optimizers go harder on them ๐ช.
Don't use this together with -flto. Relying on a linker plugin instead gives you safer and more precise information.
-flto[=n]โ okay, this is the big one, so get comfy ๐๏ธ. It runs the standard link-time optimizer. When you invoke it on source code, it generates GIMPLE (one of GCC's internal representations) and stashes it in special ELF sections of the object file. When the object files get linked, all the function bodies are read back out of those sections and treated as if they were part of the same translation unit ๐งฉ.
To use link-time optimization, you need -flto and your optimization options at both compile time and the final link. It's recommended that you compile every file in the same link with the same options, and also pass those options at link time. For example:
gcc -c -O2 -flto foo.c
gcc -c -O2 -flto bar.c
gcc -o myprog -flto -O2 foo.o bar.o
The first two commands save a bytecode version of GIMPLE into special ELF sections inside foo.o and bar.o. The last one reads that GIMPLE bytecode from foo.o and bar.o, merges the two files into one internal image, and compiles the result as usual. Because both files are merged, all the interprocedural analyses and optimizations in GCC work across the two files as if they were one. So, for example, the inliner can inline functions from bar.o into functions in foo.o and vice-versa ๐คฏ.
Another (simpler) way to turn it on is:
gcc -o myprog -flto -O2 foo.c bar.c
That generates bytecode for foo.c and bar.c, merges them into a single GIMPLE representation, and optimizes them as usual to produce myprog ๐.
The key thing to remember: to enable link-time optimizations, you have to use the GCC driver to do the link step ๐. GCC automatically does link-time optimization if any of the objects involved were compiled with -flto. If you ever want to override that automatic choice, just pass -fno-lto to the link command.
To make whole program optimization actually effective, you need to make some whole program assumptions. The compiler needs to know which functions and variables can be accessed by libraries and runtime code outside the link-time optimized unit. When the linker supports it, the linker plugin (see -fuse-linker-plugin) passes that info along about used and externally visible symbols. If the linker plugin isn't available, use -fwhole-program so the compiler can make those assumptions for you, which leads to more aggressive optimization decisions ๐.
When a file is compiled with -flto and without -fuse-linker-plugin, the object file comes out bigger than a regular one. That's because it holds GIMPLE bytecodes and the usual final code (see -ffat-lto-objects. The upside is that LTO object files can still be linked like normal object files. If -fno-lto gets passed to the linker, though, no interprocedural optimizations are applied ๐ฅฒ.
Heads up: with -fno-fat-lto-objects enabled, the compile stage is faster, but you cannot perform a regular, non-LTO link on those objects.
When it's time to make the final binary, GCC only applies link-time optimizations to files that contain bytecode. That means you can mix and match object files and libraries that have GIMPLE bytecode with ones that only have final object code. GCC automatically figures out which files to optimize in LTO mode and which to link without any extra processing ๐ง .
Generally, options given at link time override the ones given at compile time, though sometimes GCC tries to infer link-time options from the settings used on the input files ๐ต๏ธโโ๏ธ.
If you don't specify an optimization level -O at link time, GCC uses the highest optimization level that was used when compiling the object files. Just a heads up: it's generally ineffective to specify an optimization level only at link time and not at compile time, for two reasons. First, compiling without optimization skips the compiler passes that gather information needed for good link-time optimization. Second, some early optimization passes can only run at compile time, not at link time ๐.
GCC preserves some code generation flags in the bytecode, since they need to be used during the final link. Right now, the options and their settings are taken from the first object file that explicitly specifies them: -fPIC, -fpic, -fpie, -fcommon, -fexceptions, -fnon-call-exceptions, -fgnu-tm, and all the -m target flags ๐ฏ.
Certain ABI-changing flags have to match across all compilation units. If you try to override one of them at link time with a conflicting value, it gets ignored. This includes options like -freg-struct-return and -fpcc-struct-return ๐
โโ๏ธ.
Other options, like -ffp-contract, -fno-strict-overflow, -fwrapv, -fno-trapv, or -fno-strict-aliasing, get passed through to the link stage and merged conservatively for conflicting translation units. -fno-strict-overflow, -fwrapv, and -fno-trapv take precedence. For example, -ffp-contract=off takes precedence over -ffp-contract=fast. You can still override them at link time ๐
โจ.
Okay so bestie, this is where the diagnostics get a little plot-twisty ๐ฎ Options like -Wstringop-overflow get passed through to the link stage, and their setting matches the compile step at function granularity. This only matters for diagnostics emitted during optimization. Also, code transforms like inlining can make warnings turn on or off for regions of code that don't match the setting at compile time. Not the vibe, but it's real ๐
When you need to pass options to the assembler with -Wa or -Xassembler, you have two safe paths ๐ค๏ธ Either compile those translation units with -fno-lto, or use the same assembler options on every translation unit. You can also specify assembler options at LTO link time instead. โจ
To turn on debug info generation, you need -g at compile time ๐ If any input files at link time were built with debug info generation enabled, the link enables it too. Fancier debug settings like the dwarf level -gdwarf-5 have to be repeated explicitly on the linker command line, and mixing different settings across translation units is discouraged ๐
๐ Heads up: If LTO runs into objects with C linkage that are declared with incompatible types across separate translation units being linked together, it may issue a non-fatal diagnostic. This is undefined behavior according to ISO C99 6.2.7, and it's still undefined at run time. Similar diagnostics may pop up for other languages too.
LTO also lets you do interprocedural optimizations across files written in different languages, and this is honestly iconic ๐
gcc -c -flto foo.c
g++ -c -flto bar.cc
gfortran -c -flto baz.f90
g++ -o myprog -flto -O3 foo.o bar.o baz.o -lgfortran
The final link is done with g++ so you get the C++ runtime libraries, and -lgfortran gets added for the Fortran runtime libraries ๐ In general, when you mix languages in LTO mode, use the same link command options you'd use when mixing languages in a regular (non-LTO) compilation.
If object files with GIMPLE bytecode are stored in a library archive, like libfoo.a, you can extract and use them in an LTO link as long as your linker has plugin support ๐ง To make static libraries that are LTO-ready, use gcc-ar and gcc-ranlib instead of ar and ranlib. To see the symbols in object files with GIMPLE bytecode, use gcc-nm. These commands need ar, ranlib and nm to have been compiled with plugin support. At link time, add -fuse-linker-plugin so the library joins the LTO optimization party ๐
gcc -o myprog -O2 -flto -fuse-linker-plugin a.o b.o -lfoo
With the linker plugin enabled, the linker pulls the needed GIMPLE files out of libfoo.a and hands them to the running GCC, so they become part of the aggregated GIMPLE image that gets optimized ๐ฆ
If you aren't using a linker with plugin support, or you just don't enable the linker plugin, the objects inside libfoo.a still get extracted and linked as usual. They just don't take part in LTO optimization ๐ญ If you want a static library that works for both LTO optimization and regular linkage, compile its object files with -flto -ffat-lto-objects.
Link-time optimizations don't need the whole program present to work ๐ธ If your program doesn't need to export any symbols, you can combine -flto and -fwhole-program. That lets the interprocedural optimizers make more aggressive assumptions, which can mean better optimization opportunities โจ You don't need -fwhole-program when the linker plugin is active (see -fuse-linker-plugin).
LTO doesn't try to make bytecode that's portable between different host types, so no cross-platform bytecode hopes here ๐ The bytecode files are versioned with a strict version check, which means bytecode generated by one GCC version won't work with an older or newer GCC.
Also, LTO doesn't play nicely with debug info generation on systems that don't use a combination of ELF and DWARF ๐
If you give the optional n, link-time optimization and code generation run in parallel with n jobs, using an installed make program ๐โโ๏ธ The environment variable MAKE can override which program gets used.
-flto=jobserver is a power move ๐ช It uses GNU make's job server mode to figure out the number of parallel jobs, which is super useful when the Makefile calling GCC is already running in parallel. You have to prepend a + to the command recipe in the parent Makefile for this to work. It likely only works if MAKE is GNU make. Even without an option value, GCC will try to automatically detect a running GNU make job server ๐ง
-flto=auto uses GNU make's job server if it's available, and otherwise falls back to autodetecting the number of CPU threads on your system ๐ซถ
-flto-partition=algโ Picks the partitioning algorithm the link-time optimizer uses. The value is either1to1, which mirrors the original source files, orbalanced, which splits things into equally sized chunks whenever possible, ormax, which creates a new partition for every symbol where possible. Setting it tononeturns partitioning and streaming off completely. The default isbalanced.1to1can be used as a workaround for various code ordering issues, butmaxis intended for internal testing only ๐งช The valueonesays exactly one partition should be used, whilenoneskips partitioning and runs the link-time optimization step straight from the WPA phase.-flto-compression-level=nโ Sets how much compression is used for the intermediate language written to LTO object files. This only matters with LTO mode (-flto). Valid values run from0(no compression) to9(maximum compression). Values outside that range get clamped to either0or9. If you don't give the option, a default balanced compression setting is used ๐๏ธ-fuse-linker-pluginโ Turns on a linker plugin during link-time optimization. This relies on plugin support in the linker, which is available in gold or in GNU ld 2.21 or newer. It also lets object files with GIMPLE bytecode get pulled out of library archives, which improves optimization quality by exposing more code to the link-time optimizer ๐ The linker plugin tells GCC which symbols can be accessed externally (by non-LTO objects or during dynamic linking). Code quality improvements on binaries (and on shared libraries that use hidden visibility) are similar to-fwhole-program. See-fltofor a description of what this flag does and how to use it. This option is enabled by default when LTO support in GCC is turned on and GCC was configured to use a linker that supports plugins (GNU ld 2.21 or newer, or gold) ๐-ffat-lto-objectsโ Fat LTO objects are object files that contain both the intermediate language and the object code, so they work for both LTO linking and normal linking ๐ This option only does something when you compile with-flto, and it's ignored at link time.-fno-fat-lto-objectsmakes compilation faster than plain LTO, but the whole toolchain has to know about LTO. It needs a linker with plugin support for basic functionality. On top of that,nm,arandranlibneed plugin support too if you want a full-featured build environment that can make static libraries and so on. GCC provides thegcc-ar,gcc-nmandgcc-ranlibwrappers to pass the right options to those tools, and with non-fat LTO, makefiles need to be changed to use them. Modern binutils also has a plugin auto-load mechanism, so installing the linker plugin into$libdir/bfd-pluginsdoes the same job as the command wrappers (gcc-ar,gcc-nmandgcc-ranlib) ๐ The default is-fno-fat-lto-objectson targets with linker plugin support.-fcompare-elimโ After register allocation and post-register allocation instruction splitting, this finds arithmetic instructions that compute processor flags in a way similar to a comparison based on that arithmetic. If possible, it removes the explicit comparison operation ๐งน This pass only applies to certain targets that can't explicitly represent the comparison operation before register allocation is finished. Enabled at levels-O,-O2,-O3,-Os.-fcprop-registersโ After register allocation and post-register allocation instruction splitting, this runs a copy-propagation pass to try to reduce scheduling dependencies and sometimes eliminate the copy ๐ Enabled at levels-O,-O2,-O3,-Os.-fprofile-correctionโ Profiles collected from an instrumented binary for multi-threaded programs can be inconsistent because some counter updates get missed ๐ตโ๐ซ With this option, GCC uses heuristics to correct or smooth out those inconsistencies. By default, GCC emits an error message when it detects an inconsistent profile. This option is enabled by-fauto-profile.-fprofile-partial-trainingโ With-fprofile-use, all parts of a program that weren't executed during the train run get optimized aggressively for size instead of speed ๐ข Sometimes it isn't practical to train every possible hot path. For example, a program might contain functions that are specific to certain hardware, and training might not cover every hardware configuration the program runs on. With-fprofile-partial-training, profile feedback is ignored for all functions that weren't executed during the train run, so they get optimized as if they were compiled without profile feedback. This gives better performance when the train run isn't representative, but it also leads to significantly bigger code ๐ฆ-fprofile-use,-fprofile-use=pathโ Enables profile feedback-directed optimizations, plus the following optimizations, many of which are usually only worth it when profile feedback is available ๐ฅ
okay so -fprofile-use also flips on this whole crew of optimizations, and most of them are only really worth it when you have profile feedback ๐ฅ
-fbranch-probabilities, -fprofile-values, -funroll-loops, -fpeel-loops, -ftracer, -fvpt, -finline-functions, -fipa-cp, -fipa-cp-clone, -fipa-bit-cp, -fpredictive-commoning, -fsplit-loops, -funswitch-loops, -fgcse-after-reload, -ftree-loop-vectorize, -ftree-slp-vectorize, -fvect-cost-model=dynamic, -ftree-loop-distribute-patterns, -fprofile-reorder-functions โจ
Bestie, heads up: you must generate profiling information before you can use this one. No shortcuts ๐
By default, GCC throws an error if the feedback profiles don't match your source code. You can downgrade that to a warning with -Wno-error=coverage-mismatch, but be warned that this can lead to poorly optimized code ๐ Also, if the feedback profiles don't exist at all, GCC warns you by default (see -Wmissing-profile).
If you give it a path, GCC goes looking in that path for the profile feedback data files. See -fprofile-dir ๐ฆ
๐ -fauto-profile, -fauto-profile=path
Turns on sampling-based feedback-directed optimizations, plus the following ones, which are mostly only profitable when profile feedback is available:
-fbranch-probabilities, -fprofile-values, -funroll-loops, -fpeel-loops, -ftracer, -fvpt, -finline-functions, -fipa-cp, -fipa-cp-clone, -fipa-bit-cp, -fpredictive-commoning, -fsplit-loops, -funswitch-loops, -fgcse-after-reload, -ftree-loop-vectorize, -ftree-slp-vectorize, -fvect-cost-model=dynamic, -ftree-loop-distribute-patterns, -fprofile-correction
path is the name of a file holding AutoFDO profile information. If you leave it out, it defaults to fbdata.afdo in the current directory ๐
To make an AutoFDO profile data file, you run your program with the perf utility on a supported GNU/Linux target system. Check out https://perf.wiki.kernel.org/ for more info ๐ซถ
Something like this:
perf record -e br_inst_retired:near_taken -b -o perf.data \
-- your_program
Then you use the create_gcov tool to turn that raw profile data into something GCC can actually read. You also have to hand it the unstripped binary for your program. See https://github.com/google/autofdo ๐
create_gcov --binary=your_program.unstripped --profile=perf.data \
--gcov=profile.afdo
The following options control how the compiler handles floating-point arithmetic. They trade speed against correctness, so you have to turn each one on yourself. Nothing here happens by accident ๐ง
๐
-ffloat-store
Stops floating-point variables from living in registers, and blocks any other option that might change whether a floating-point value comes from a register or from memory.
This is for avoiding the sneaky excess precision you get on machines like the 68000, where the floating registers (of the 68881) hold more precision than a double is supposed to have. The x86 architecture does this too. For most programs, the extra precision is only a good thing, but a few programs depend on the exact IEEE floating-point definition. For those, use -ffloat-store after you've changed them to store all the important intermediate results in variables โจ
๐ธ -fexcess-precision=style
This gives you more say over excess precision on machines where floating-point operations happen in a format with more precision or range than IEEE and the interchange floating-point types. By default, -fexcess-precision=fast is in effect, which means operations can run in a wider precision than the source types if that makes the code faster, and it's unpredictable when rounding to the source types actually happens.
When compiling C, if you specify -fexcess-precision=standard, excess precision follows the rules in ISO C99. Casts and assignments both cause values to be rounded to their semantic types (whereas -ffloat-store only affects assignments). This option is enabled by default for C if a strict conformance option like -std=c99 is used. -ffast-math enables -fexcess-precision=fast by default no matter whether a strict conformance option is used ๐
-fexcess-precision=standard isn't implemented for languages other than C. On x86, it does nothing if -mfpmath=sse or -mfpmath=sse+387 is specified. In the first case, IEEE semantics apply with no excess precision, and in the second, rounding is unpredictable ๐
๐ฅ -ffast-math
Sets -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans, -fcx-limited-range and -fexcess-precision=fast.
This also causes the preprocessor macro __FAST_MATH__ to be defined.
No -O option turns this on except -Ofast, since it can give incorrect output for programs that depend on an exact implementation of IEEE or ISO rules for math functions. But if your program doesn't need those guarantees, it might give you faster code ๐จ
๐ฆ -fno-math-errno
Don't set errno after calling math functions that run as a single instruction, like sqrt. A program that relies on IEEE exceptions for math error handling might want this flag for the speed boost while keeping IEEE arithmetic compatibility ๐
No -O option turns this on, because it can give incorrect output for programs that depend on exact IEEE or ISO math behavior. It might, however, make faster code for programs that don't need those guarantees.
The default is -fmath-errno.
On Darwin systems, the math library never sets errno. So there's no reason for the compiler to think it might, and -fno-math-errno is the default there ๐
๐ง -funsafe-math-optimizations
Allows floating-point optimizations that (a) assume arguments and results are valid and (b) may violate IEEE or ANSI standards. When it's used at link time, it can pull in libraries or startup files that change the default FPU control word or make other similar optimizations ๐
No -O option turns this on, since it can give incorrect output for programs that depend on exact IEEE or ISO math rules. It might, however, yield faster code for programs that don't need those guarantees. It enables -fno-signed-zeros, -fno-trapping-math, -fassociative-math and -freciprocal-math.
The default is -fno-unsafe-math-optimizations.
๐ -fassociative-math
Allows re-association of operands in series of floating-point operations. This violates the ISO C and C++ standard by possibly changing the computed result.
โ ๏ธ Heads up, bestie: re-ordering can change the sign of zero, ignore NaNs, and inhibit or create underflow or overflow. That means you can't use it on code that depends on rounding behavior, like (x + 2**52) - 2**52. It can also reorder floating-point comparisons, so don't use it where ordered comparisons are required.
This option needs both -fno-signed-zeros and -fno-trapping-math to be in effect. It also doesn't make much sense with -frounding-math. For Fortran, the option is automatically enabled when both -fno-signed-zeros and -fno-trapping-math are in effect.
The default is -fno-associative-math.
โญ -freciprocal-math
Lets the reciprocal of a value be used instead of dividing by that value, if that enables optimizations. For example, x / y can be replaced with x * (1/y), which is useful if (1/y) is subject to common subexpression elimination. Heads up that this loses precision and increases the number of flops operating on the value ๐ค
The default is -fno-reciprocal-math.
๐ -ffinite-math-only
Allows floating-point optimizations that assume arguments and results are not NaNs or +-Infs.
No -O option turns this on, since it can give incorrect output for programs that depend on exact IEEE or ISO math rules. It might, however, yield faster code for programs that don't need those guarantees.
The default is -fno-finite-math-only.
๐ซถ -fno-signed-zeros
Allows floating-point optimizations that ignore the signedness of zero. IEEE arithmetic gives distinct +0.0 and -0.0 values with their own behavior, and that stops you from simplifying expressions like x+0.0 or 0.0*x (even with -ffinite-math-only). This option says the sign of a zero result isn't significant ๐ธ
The default is -fsigned-zeros.
๐ -fno-trapping-math
Compiles code assuming floating-point operations can't generate user-visible traps. Those traps include division by zero, overflow, underflow, inexact result and invalid operation. This option requires -fno-signaling-nans to be in effect. Turning it on might give you faster code if you rely on "non-stop" IEEE arithmetic, for example ๐ฆ
โ ๏ธ This option should never be turned on by any -O option, since it can give incorrect output for programs that depend on exact IEEE or ISO math rules.
The default is -ftrapping-math.
๐ -frounding-math
Disables transformations and optimizations that assume the default floating-point rounding behavior. That's round-to-zero for all floating-point to integer conversions, and round-to-nearest for all other arithmetic truncations. You should specify this for programs that change the FP rounding mode dynamically, or that might run with a non-default rounding mode. It disables constant folding of floating-point expressions at compile time (which the rounding mode could affect), and it disables arithmetic transformations that are unsafe when rounding depends on the sign.
The default is -fno-rounding-math.
This option is experimental and doesn't currently guarantee that it disables every GCC optimization affected by rounding mode. Future versions of GCC may give finer control over this setting using C99's FENV_ACCESS pragma. This command-line option will be used to set the default state for FENV_ACCESS ๐ฅ
-fsignaling-nansโ okay so this one is for IEEE signaling NaNs, which are allowed to throw user-visible traps during floating-point ops. Turn it on and GCC assumes that can really happen, so it switches off optimizations that might change how many exceptions show up with signaling NaNs. It implies-ftrapping-math๐ฅ
Flipping this on also defines the preprocessor macro __SUPPORT_SNAN__ โจ
The default is -fno-signaling-nans ๐
โ ๏ธ Bestie, this one is experimental. It does NOT currently guarantee that every GCC optimization affecting signaling NaN behavior gets disabled. ๐ญ
-fno-fp-int-builtin-inexactโ don't let the built-in functionsceil,floor,round, andtrunc(plus theirfloatandlong doubleversions) generate code that raises theinexactfloating-point exception for noninteger arguments ๐ธ
ISO C99 and C11 are fine with these functions raising inexact, but ISO/IEC TS 18661-1:2014 (the C bindings to IEEE 754-2008, now part of ISO C2X) is not. ๐
The default is -ffp-int-builtin-inexact, which lets the exception be raised, unless C2X or a later C standard is selected. This option does nothing unless -ftrapping-math is in effect.
Even with -fno-fp-int-builtin-inexact, if these functions end up calling a library function, inexact can still be raised if that library doesn't follow TS 18661. Not on us, periodt ๐
-fsingle-precision-constantโ floating-point constants get treated as single precision instead of being quietly converted into double-precision constants ๐ฆ-fcx-limited-rangeโ when this is on, GCC is told that a range reduction step isn't needed for complex division ๐ง It also means there's no checking whether a complex multiplication or division result isNaN + I*NaN, so there's no rescue attempt for that situation either.
The default is -fno-cx-limited-range, but -ffast-math turns it on ๐ฅ
This option controls the default setting of the ISO C99 CX_LIMITED_RANGE pragma. It applies to all languages, not just one, which is very iconic of it ๐
-fcx-fortran-rulesโ complex multiplication and division follow Fortran rules ๐ Range reduction is done as part of complex division, but there's no checking forNaN + I*NaNresults, and no attempt to rescue that case.
The default is -fno-cx-fortran-rules ๐
Okay now for the optimizations that might make your code faster ๐โโ๏ธ๐จ None of these get switched on by any -O options, so you have to ask for them yourself. This section also has experimental options that might produce broken code, so, bestie, be careful ๐
-fbranch-probabilitiesโ after you run a program compiled with-fprofile-arcs, you compile it again with-fbranch-probabilitiesso the optimizer can use how many times each branch was taken โจ When a program compiled with-fprofile-arcsexits, it saves arc execution counts to a file calledsourcename.gcdafor each source file. That data is super dependent on the structure of the generated code, so you have to use the same source code and the same optimization options for both compilations. No switching it up mid-way ๐ญ
With -fbranch-probabilities, GCC puts a REG_BR_PROB note on each JUMP_INSN and CALL_INSN. These can be used to improve optimization. Right now they're only used in one place: in reorg.c. Instead of guessing which path a branch is most likely to take, the REG_BR_PROB values are used to figure out exactly which path is taken more often ๐ง
Enabled by -fprofile-use and -fauto-profile ๐ซถ
-fprofile-valuesโ when combined with-fprofile-arcs, this adds code that gathers some data about values of expressions in the program ๐ฆ
With -fbranch-probabilities, it reads back the data gathered from profiling those values so it can use them in optimizations ๐
Enabled by -fprofile-generate, -fprofile-use, and -fauto-profile โจ
-fprofile-reorder-functionsโ function reordering based on profile instrumentation collects the first time each function runs, then orders those functions in ascending order ๐ธ
Enabled with -fprofile-use ๐
-fvptโ when combined with-fprofile-arcs, this tells the compiler to add code that gathers info about values of expressions ๐
With -fbranch-probabilities, it reads back that data and actually performs optimizations based on it. Right now those optimizations include specializing division operations using what the compiler knows about the value of the denominator ๐งฎ
Enabled with -fprofile-use and -fauto-profile ๐
-frename-registersโ tries to avoid false dependencies in scheduled code by using registers left over after register allocation ๐ง This one most benefits processors with lots of registers ๐
Heads up though: depending on the debug information format the target uses, it can make debugging impossible, since variables no longer stay in a "home register" ๐
Enabled by default with -funroll-loops โจ
-fschedule-fusionโ performs a target-dependent pass over the instruction stream to schedule instructions of the same type together. Some targets can run them more efficiently when they're next to each other in the instruction flow ๐ฅ
Enabled at levels -O2, -O3, -Os ๐
-ftracerโ does tail duplication to enlarge the superblock size. This simplifies the control flow of the function, which lets other optimizations do a better job ๐ฆ
Enabled by -fprofile-use and -fauto-profile ๐ซถ
-funroll-loopsโ unrolls loops whose number of iterations can be figured out at compile time or when the loop is entered ๐ It implies-frerun-cse-after-loop,-fweb, and-frename-registers. It also turns on complete loop peeling, which means fully removing loops with a small constant number of iterations ๐ธ
Fair warning: this option makes code larger, and it may or may not make it run faster ๐
Enabled by -fprofile-use and -fauto-profile โจ
-funroll-all-loopsโ unrolls ALL loops, even ones where the number of iterations is uncertain when the loop is entered ๐ญ This usually makes programs run more slowly, so, be intentional ๐ It implies the same options as-funroll-loops.-fpeel-loopsโ peels loops that have enough info to show they don't roll much, either from profile feedback or static analysis ๐ง It also turns on complete loop peeling, meaning complete removal of loops with a small constant number of iterations ๐
Enabled by -O3, -fprofile-use, and -fauto-profile ๐
-fmove-loop-invariantsโ enables the loop invariant motion pass in the RTL loop optimizer. It's the move that pulls stuff that doesn't change out of the loop ๐
Enabled at level -O1 and higher, except for -Og ๐ซถ
-fsplit-loopsโ splits a loop into two if it has a condition that's always true for one side of the iteration space and always false for the other ๐ชโจ
Enabled by -fprofile-use and -fauto-profile ๐
-funswitch-loopsโ moves branches with loop invariant conditions out of the loop. Duplicates of the loop end up on both branches, each modified according to the result of the condition ๐ฆ
Enabled by -fprofile-use and -fauto-profile ๐
-fversion-loops-for-stridesโ if a loop iterates over an array with a variable stride, GCC creates another version of the loop that assumes the stride is always one ๐ธ For example:
for (int i = 0; i < n; ++i)
x[i * stride] = ...;
becomes:
if (stride == 1)
for (int i = 0; i < n; ++i)
x[i] = ...;
else
for (int i = 0; i < n; ++i)
x[i * stride] = ...;
This is especially useful for assumed-shape arrays in Fortran, where (for example) it allows better vectorization by assuming contiguous accesses ๐ This flag is enabled by default at -O3. It's also enabled by -fprofile-use and -fauto-profile ๐ซถ
-ffunction-sections,-fdata-sectionsโ each function or data item gets its own section in the output file, as long as the target supports arbitrary sections ๐งฉ The name of the function or data item decides the section's name in the output file.
Use these on systems where the linker can optimize for locality of reference in the instruction space. Most systems using the ELF object format have linkers with that kind of optimization. On AIX, the linker rearranges sections (CSECTs) based on the call graph. The performance impact varies, so, vibe check it first โจ
Together with linker garbage collection (the linker --gc-sections option), these options may lead to smaller statically-linked executables (after stripping) ๐
On ELF/DWARF systems, these options don't degrade the quality of the debug information ๐ There could be issues with other object file or debug info formats though ๐ฌ
Only use these options when there are significant benefits. When you specify them, the assembler and linker create larger object and executable files, and they're also slower ๐ข These options affect code generation. They prevent optimizations by the compiler and assembler that use relative locations inside a translation unit, since those locations aren't known until link time. An example of one such optimization is relaxing calls to short call instructions ๐
-fstdarg-optโ optimizes the prologue of variadic argument functions with respect to how those arguments are used ๐
NOTE: In Ubuntu 14.10 and later versions,-fstack-protector-strongis enabled by default for C, C++, ObjC, and ObjC++, as long as none of-fno-stack-protector,-nostdlib, or-ffreestandingare found. ๐ก๏ธ
-fsection-anchorsโ tries to reduce the number of symbolic address calculations by using shared "anchor" symbols to address nearby objects ๐ฆ This can help reduce the number of GOT entries and GOT accesses on some targets ๐
Take this function foo:
static int a, b, c;
int foo (void) { return a + b + c; }
Usually it calculates the addresses of all three variables. But if you compile it with -fsection-anchors, it accesses the variables from a common anchor point instead โจ The effect is similar to this pseudocode (which isn't valid C, so don't try to compile it, bestie ๐ญ):
int foo (void)
{
register int *xr = &x;
return xr[&a - &x] + xr[&b - &x] + xr[&c - &x];
}
Not all targets support this option. ๐ซถ
Okay so, --param name=value lets you poke at the little constants GCC uses to decide how much optimizing to do ๐
. For example, GCC won't inline a function that has too many instructions in it. You can tweak some of these knobs on the command line with --param. ๐ฅ
โ ๏ธ Bestie, the names and what the values mean are tied to GCC's internals and can change without notice in future releases. Don't build your whole life on them ๐
If you want the minimal, maximal, and default value of a parameter, use --help=param -Q options โจ
In every case the value is an integer. These names are recognized for all targets ๐
predictable-branch-outcomeโ If a branch is predicted to be taken with a probability lower than this threshold (in percent), it counts as well predictable ๐ฎmax-rtl-if-conversion-insnsโ RTL if-conversion tries to get rid of conditional branches around a block and swap them for conditionally executed instructions ๐ฆ This sets the max number of instructions in a block that can even be considered for if-conversion. The compiler also uses other heuristics to decide if if-conversion is actually worth it.max-rtl-if-conversion-predictable-costandmax-rtl-if-conversion-unpredictable-costโ Same if-conversion vibe, but these set the max permissible cost for the sequence it would generate. One is for when the branch is statically determined to be predictable, the other for when it isn't ๐ The units match GCC's internalseq_costmetric. The compiler tries to pick a reasonable default for these using theBRANCH_COSTtarget macro.max-crossjump-edgesโ The max number of incoming edges to consider for cross-jumping ๐ธ The algorithm behind-fcrossjumpingisO(N^2)in the number of incoming edges to each block, so bigger values mean more aggressive optimization. The catch is longer compile times for probably a small win in executable size ๐ขmin-crossjump-insnsโ The minimum number of instructions that must match at the end of two blocks before cross-jumping happens on them. This value gets ignored when every instruction in the block being cross-jumped from is already matched ๐max-grow-copy-bb-insnsโ The max code size expansion factor when copying basic blocks instead of jumping. The expansion is measured relative to a jump instruction ๐งmax-goto-duplication-insnsโ The max number of instructions to duplicate into a block that jumps to a computed goto. GCC factors computed gotos early to avoidO(N^2)behavior in a bunch of passes, then unfactors them as late as possible. Only computed jumps at the end of basic blocks with no more thanmax-goto-duplication-insnsinstructions get unfactored ๐max-delay-slot-insn-searchโ The max number of instructions to check when hunting for something to fill a delay slot ๐ Past this arbitrary number, the time saved by filling the slot is basically nothing, so GCC stops searching. Bigger values mean more aggressive optimization, longer compile times, and probably a small improvement in execution time โฑ๏ธmax-delay-slot-live-searchโ When filling delay slots, the max number of instructions to check while looking for a block with valid live register information. Cranking this arbitrary value up means more aggressive optimization and longer compile times ๐ This parameter should get removed once the delay slot code is rewritten to maintain the control-flow graph.max-gcse-memoryโ The approximate max memory that can be allocated for global common subexpression elimination ๐ง If the optimization would need more than this, it just doesn't happen.max-gcse-insertion-ratioโ If the ratio of expression insertions to deletions is bigger than this for any expression, RTL PRE inserts or removes that expression. That means it leaves partially redundant computations sitting in the instruction stream ๐คทโโ๏ธmax-pending-list-lengthโ The max number of pending dependencies scheduling allows before it flushes the current state and starts over ๐งน Big functions with few branches or calls can build up excessively large lists that waste memory and resources for no reason.max-modulo-backtrack-attemptsโ The max number of backtrack attempts the scheduler should make when modulo scheduling a loop ๐ Larger values can exponentially increase compile time, so don't go wild ๐max-inline-insns-singleโ A handful of parameters control the tree inliner, and this one sets the max number of instructions (counted in GCC's internal representation) in a single function that the tree inliner will consider for inlining ๐ It only affects functions declaredinlineand methods implemented inside a class declaration in C++.max-inline-insns-autoโ With-finline-functions(which comes with-O3), a whole bunch of functions that would normally never be considered for inlining get looked at โจ For those, a different and more restrictive limit applies than for functions declared inline. You set it with--param max-inline-insns-auto.max-inline-insns-smallโ The bound that applies to calls considered relevant under-finline-small-functions๐ทmax-inline-insns-sizeโ The bound that applies to calls being optimized for size ๐ A little growth can be a good thing here, since it helps anticipate optimization opportunities that inlining exposes.uninlined-function-insnsโ The number of instructions the inliner counts as function overhead, like the function prologue and epilogue ๐uninlined-function-timeโ The extra time the inliner counts as function overhead, like the time it takes to run the function's prologue and epilogue โณinline-heuristics-hint-percentโ The scale (in percents) applied toinline-insns-single,inline-insns-single-O2, andinline-insns-autowhen the inline heuristics hint that inlining is super profitable and will unlock later optimizations ๐uninlined-thunk-insnsanduninlined-thunk-timeโ Same deal as--param uninlined-function-insnsand--param uninlined-function-time, but these apply to function thunks ๐งตinline-min-speedupโ When the estimated performance improvement of caller plus callee runtime goes over this threshold (in percent), the function can be inlined no matter what the limits on--param max-inline-insns-singleand--param max-inline-insns-autosay ๐โโ๏ธ๐จlarge-function-insnsโ The limit that defines really large functions ๐ For functions bigger than this after inlining, inlining gets constrained by--param large-function-growth. This one is mostly there to avoid extreme compile times caused by the non-linear algorithms the back end uses.large-function-growthโ The max growth of a large function caused by inlining, in percents. For example, a value of100limits large function growth to 2.0 times the original size ๐large-unit-insnsโ The limit that defines a large translation unit ๐ฆ Growth from inlining into units bigger than this is limited by--param inline-unit-growth. For small units, that limit could be too tight. Picture a unit with function A, which is inline, and function B, which just calls A three times. If B is small compared to A, the unit's growth is 300% and that inlining is still totally sane ๐ฅฐ For really large units full of small inlineable functions, though, the overall unit growth limit is needed to stop the code size from exploding exponentially. So for smaller units, the size gets bumped up to--param large-unit-insnsbefore--param inline-unit-growthis applied.inline-unit-growthโ The max overall growth of the compilation unit caused by inlining. For example, a value of20limits unit growth to 1.2 times the original size ๐ฟ Cold functions (marked cold with an attribute or by profile feedback) don't count toward the unit size ๐งipa-cp-unit-growthโ The max overall growth of the compilation unit caused by interprocedural constant propagation. A value of10limits unit growth to 1.1 times the original size ๐ซlarge-stack-frameโ The limit that defines large stack frames ๐ฅ While inlining, the algorithm tries not to grow past this limit by too much.large-stack-frame-growthโ The max growth of large stack frames caused by inlining, in percents. For example, a value of1000limits large stack frame growth to 11 times the original size ๐max-inline-insns-recursiveandmax-inline-insns-recursive-autoโ The max number of instructions an out-of-line copy of a self-recursive inline function can grow into through recursive inlining ๐--param max-inline-insns-recursiveapplies to functions declaredinline. For functions that aren't declared inline, recursive inlining only happens when-finline-functions(included in-O3) is enabled, and then--param max-inline-insns-recursive-autoapplies instead ๐ซmax-inline-recursive-depthandmax-inline-recursive-depth-autoโ The max recursion depth used for recursive inlining ๐ช
Anyway, --param max-inline-recursive-depth is the one for functions you actually declared inline ๐. For functions that aren't declared inline, recursive inlining only happens when -finline-functions is turned on (it comes along with -O3). If that's the case, --param max-inline-recursive-depth-auto takes over instead ๐
.
min-inline-recursive-probabilityโ ngl this one's a vibe check ๐ฎ. Recursive inlining is only worth it for functions that recurse deeply on average. For functions with barely any recursion depth, it can backfire by making the prologue bigger or the function body more complicated for the other optimizers ๐ญ. When profile feedback is available (see-fprofile-generate), the actual recursion depth can be guessed from how likely a function is to recurse through a given call expression. This parameter only allows inlining for call expressions whose probability is higher than the threshold you set, in percents ๐.early-inlining-insnsโ how much growth the early inliner is allowed to make. Basically, it lets it inline more in code that has a large abstraction penalty ๐ง.max-early-inliner-iterationsโ the limit on how many iterations the early inliner runs. This mostly bounds how many nested indirect calls it can resolve. Deeper chains still get handled by late inlining ๐ฐ๏ธ.comdat-sharing-probabilityโ the percent chance that C++ inline functions with comdat visibility get shared across multiple compilation units ๐ค.profile-func-internal-idโ controls whether the function's internal id gets used in the profile database lookup. If it's0, the compiler uses an id based on the function's assembler name and filename, which makes old profile data more forgiving when the source changes, like when functions get reordered ๐ฆ.min-vect-loop-boundโ the minimum number of iterations under which loops won't be vectorized when-ftree-vectorizeis used. The number of iterations after vectorization has to be greater than this value for vectorization to happen ๐ฏ.gcse-cost-distance-ratioโ a scaling factor for working out the max distance an expression can move during GCSE optimizations. It's only supported in the code hoisting pass right now. The bigger the ratio, the more aggressive the hoisting is for simple expressions (the ones costing less thangcse-unrestricted-cost). Setting it to0disables hoisting of simple expressions ๐ซ.gcse-unrestricted-costโ the cost (roughly the cost of one typical machine instruction) at which GCSE optimizations stop limiting how far an expression can travel. This is also only supported in the code hoisting pass. The lower the cost, the more aggressive the hoisting is. Setting it to0lets all expressions travel unrestricted distances ๐.max-hoist-depthโ how deep the search goes in the dominator tree for expressions to hoist. It's there to avoid quadratic behavior in the hoisting algorithm. A value of0means no limit on the search, but compiling huge functions may get slower ๐ข.max-tail-merge-comparisonsโ the maximum number of similar basic blocks a block gets compared against. It's used to avoid quadratic behavior in tree tail merging ๐ .max-tail-merge-iterationsโ the maximum number of iterations of the pass over the function. It limits compilation time in tree tail merging โฑ๏ธ.store-merging-allow-unalignedโ lets the store merging pass introduce unaligned stores, as long as that's legal ๐งฉ.max-stores-to-mergeโ the maximum number of stores the store merging pass will try to combine into wider stores ๐.max-unrolled-insnsโ the maximum number of instructions a loop can have and still get unrolled. If a loop does get unrolled, this also decides how many times the loop code is unrolled ๐.max-average-unrolled-insnsโ the maximum number of instructions, biased by their execution probabilities, that a loop can have and still get unrolled. If it's unrolled, this also decides how many times the loop code is unrolled ๐.max-unroll-timesโ the maximum number of unrollings of a single loop ๐.max-peeled-insnsโ the maximum number of instructions a loop can have and still get peeled. If it's peeled, this also decides how many times the loop code is peeled ๐ง .max-peel-timesโ the maximum number of peelings of a single loop ๐ง .max-peel-branchesโ the maximum number of branches on the hot path through the peeled sequence ๐ฅ.max-completely-peeled-insnsโ the maximum number of insns in a completely peeled loop ๐ฅ.max-completely-peel-timesโ the maximum number of iterations a loop can have and still be suitable for complete peeling ๐.max-completely-peel-loop-nest-depthโ the maximum depth of a loop nest that's suitable for complete peeling ๐ช.max-unswitch-insnsโ the maximum number of insns in an unswitched loop ๐.max-unswitch-levelโ the maximum number of branches unswitched in a single loop ๐ช.lim-expensiveโ the minimum cost for an expression to count as expensive in loop invariant motion ๐ธ.min-loop-cond-split-probโ when FDO profile information is available, this sets the minimum probability threshold a semi-invariant condition statement needs in order to trigger a loop split โ๏ธ.iv-consider-all-candidates-boundโ the bound on the number of candidates for induction variables. Below this number, every candidate gets considered for each use in induction variable optimizations. Above it, only the most relevant candidates are considered, to avoid quadratic time complexity ๐ฏ.iv-max-considered-usesโ the induction variable optimizations give up on any loop that has more induction variable uses than this ๐.iv-always-prune-cand-set-boundโ if the number of candidates in the set is smaller than this value, it always tries to remove unnecessary ivs from the set when adding a new one ๐งน.avg-loop-niterโ the average number of iterations of a loop ๐ข.dse-max-object-sizeโ the maximum size (in bytes) of objects that dead store elimination tracks bytewise. Larger values may mean longer compilation times ๐ฆ.dse-max-alias-queries-per-storeโ the maximum number of queries into the alias oracle per store. Larger values mean longer compilation times, but they may remove more dead stores ๐๏ธ.scev-max-expr-sizeโ the bound on the size of expressions used in the scalar evolutions analyzer. Large expressions slow the analyzer down ๐.scev-max-expr-complexityโ the bound on the complexity of expressions in the scalar evolutions analyzer. Complex expressions slow the analyzer down ๐ง .max-tree-if-conversion-phi-argsโ the maximum number of arguments in a PHI supported by tree if conversion, unless the loop is marked with a simd pragma ๐งฉ.vect-max-version-for-alignment-checksโ the maximum number of run-time checks that can be performed when doing loop versioning for alignment in the vectorizer ๐.vect-max-version-for-alias-checksโ the maximum number of run-time checks that can be performed when doing loop versioning for alias in the vectorizer ๐.vect-max-peeling-for-alignmentโ the maximum number of loop peels to enhance access alignment for the vectorizer. A value of-1means no limit โพ๏ธ.max-iterations-to-trackโ the maximum number of iterations of a loop that the brute-force algorithm for analyzing the number of iterations of the loop tries to evaluate ๐งฎ.hot-bb-count-fractionโ the denominator n of the fraction 1/n of the maximal execution count of a basic block in the entire program that a basic block needs to at least have in order to be considered hot. The default is10000, which means a basic block is considered hot if its execution count is greater than 1/10000 of the maximal execution count.0means it's never considered hot. Used in non-LTO mode ๐ฅ.hot-bb-count-ws-permilleโ the number of most executed permilles, ranging from0to1000, of the profiled execution of the entire program that a basic block's execution count must be part of in order to be considered hot. The default is990, which means a basic block is considered hot if its execution count contributes to the upper 990 permilles, or 99.0%, of the profiled execution of the entire program.0means it's never considered hot. Used in LTO mode ๐ก๏ธ.hot-bb-frequency-fractionโ the denominator n of the fraction 1/n of the execution frequency of the entry block of a function that a basic block of that function needs to at least have in order to be considered hot. The default is1000, which means a basic block is considered hot in a function if it's executed more frequently than 1/1000 of the frequency of the function's entry block.0means it's never considered hot ๐ซ .unlikely-bb-count-fractionโ the denominator n of the fraction 1/n of the number of profiled runs of the entire program below which a basic block's execution count must fall for the block to be considered unlikely executed. The default is20, which means a basic block is considered unlikely executed if it runs in fewer than 1/20, or 5%, of the program's runs.0means it's always considered unlikely executed ๐ฅถ.max-predicted-iterationsโ the maximum number of loop iterations we predict statically. This is useful when a function has one loop with a known bound and another with an unknown bound. The known number of iterations gets predicted correctly, while the unknown number averages to roughly10. That makes the loop without bounds look artificially cold compared to the other one ๐ง.builtin-expect-probabilityโ ๐ฎ lets you dial in how likely the expression is to land on the specified value. It takes a percentage, so anywhere from0 ... 100๐ฏbuiltin-string-cmp-inline-lengthโ the longest a constant string can be for a builtin string cmp call to still be eligible for inlining ๐งตalign-thresholdโ picks a fraction of the max execution frequency a basic block in a function can hit, and that fraction decides whether the block gets aligned ๐align-loop-iterationsโ loops that are expected to iterate at least this many times get aligned ๐tracer-dynamic-coverageandtracer-dynamic-coverage-feedbackโ ๐ once this percentage of executed instructions is covered, superblock formation stops, so code size doesn't balloon for no reason โจtracer-dynamic-coverage-feedbackonly matters when profile feedback is available. Real profiles are way less balanced than statically estimated ones, so the threshold can be a bigger value ๐ง
tracer-max-code-growthโ stop tail duplication once code growth hits this percentage. Honestly kinda artificial ๐ซ Most of the duplicates get wiped out later in cross jumping, so this can be set much higher than the code growth you actually want ๐tracer-min-branch-ratioโ stop reverse growth when the reverse probability of the best edge drops below this threshold (in percent) ๐tracer-min-branch-probabilityandtracer-min-branch-probability-feedbackโ stop forward growth if the best edge's probability is lower than this threshold ๐ฆ- Same deal as dynamic coverage, there are two versions.
tracer-min-branch-probability-feedbackis for compiling with profile feedback, andtracer-min-branch-probabilityis for compiling without it. The feedback one needs to be more conservative (higher) so the tracer actually stays effective ๐ช
- Same deal as dynamic coverage, there are two versions.
stack-clash-protection-guard-sizeโ sets the size of the operating system provided stack guard as 2 raised to num bytes. Higher values can mean fewer explicit probes ๐ก๏ธ
๐จ bestie, if this value is larger than the operating system provided guard, your code is left wide open to stack clash style attacks ๐
stack-clash-protection-probe-intervalโ stack clash protection probes stack space as it gets allocated ๐ This param sets the maximum distance between probes into the stack, as 2 raised to num bytes. Higher values may reduce the number of explicit probes, too.
๐จ Same warning here: a value larger than the operating system provided guard leaves code vulnerable to stack clash style attacks ๐ญ
max-cse-path-lengthโ the maximum number of basic blocks on a path that CSE considers ๐ค๏ธmax-cse-insnsโ the maximum number of instructions CSE processes before it flushes ๐งน
ggc-min-expandโ okay so GCC has its own garbage collector managing its own memory ๐๏ธ This sets the minimum percentage the collector's heap is allowed to expand between collections. Tuning it may speed up compilation, but it has zero effect on code generation ๐- The default is
30% + 70% * (RAM/1GB), with an upper bound of100%when RAM is>= 1GB. If"getrlimit"is available, "RAM" means the smallest of actual RAM andRLIMIT_DATAorRLIMIT_AS. If GCC can't calculate RAM on a platform, the lower bound of30%is used. - Setting this and
ggc-min-heapsizeto zero causes a full collection at every single opportunity. It's extremely slow ๐ข but it can be useful for debugging ๐ง
- The default is
ggc-min-heapsizeโ the minimum size the garbage collector's heap has to hit before it starts bothering to collect garbage ๐ง The first collection happens after the heap expands byggc-min-expand%beyondggc-min-heapsize. Again, tuning this may speed up compilation, with no effect on code generation ๐ธ- The default is the smaller of
RAM/8,RLIMIT_RSS, or a limit that tries to make sureRLIMIT_DATAorRLIMIT_ASdon't get exceeded. It has a lower bound of4096(four megabytes) and an upper bound of131072(128 megabytes). If GCC can't calculate RAM on a platform, the lower bound is used. - Setting this very large effectively disables garbage collection ๐ Setting this and
ggc-min-expandto zero causes a full collection at every opportunity.
- The default is the smaller of
max-reload-search-insnsโ the max number of instructions reload should look backward through for an equivalent register ๐ Bigger values mean more aggressive optimization, so compile time goes up for probably slightly better performance โณmax-cselib-memory-locationsโ the max number of memory locations cselib should take into account ๐งฉ Bigger values mean more aggressive optimization, so compile time goes up for probably slightly better performance โณmax-sched-ready-insnsโ the max number of instructions ready to be issued that the scheduler should consider at any given moment during the first scheduling pass ๐ Bigger values mean more thorough searches, so compile time goes up for probably little benefit ๐คทโโ๏ธmax-sched-region-blocksโ the max number of blocks in a region considered for interblock scheduling ๐งฑmax-pipeline-region-blocksโ the max number of blocks in a region considered for pipelining in the selective scheduler ๐งฑmax-sched-region-insnsโ the max number of insns in a region considered for interblock scheduling ๐ฆmax-pipeline-region-insnsโ the max number of insns in a region considered for pipelining in the selective scheduler ๐ฆmin-spec-probโ the minimum probability (in percents) of reaching a source block for interblock speculative scheduling ๐ฒmax-sched-extend-regions-itersโ the max number of iterations through the CFG to extend regions ๐บ๏ธ A value of0disables region extensions.max-sched-insn-conflict-delayโ the max conflict delay an insn can have and still be considered for speculative motion ๐โโ๏ธsched-spec-prob-cutoffโ the minimal probability of speculation success (in percents) so that speculative insns get scheduled ๐ฏsched-state-edge-prob-cutoffโ the minimum probability an edge needs to have before the scheduler saves its state across it ๐พsched-mem-true-dep-costโ the minimal distance (in CPU cycles) between a store and a load targeting the same memory locations ๐ฐ๏ธselsched-max-lookaheadโ the max size of the lookahead window for selective scheduling ๐ It's basically how deep the search goes for available instructions ๐ณ๏ธselsched-max-sched-timesโ the max number of times an instruction gets scheduled during selective scheduling ๐ This is the cap on how many iterations the instruction can be pipelined through ๐ชselsched-insns-to-renameโ the max number of best instructions in the ready list that get considered for renaming in the selective scheduler โ๏ธsms-min-scโ the minimum stage count value that the swing modulo scheduler generates ๐ขmax-last-value-rtlโ the max size, measured as the number of RTLs, that the combiner can record in an expression for a pseudo register as its last known value ๐max-combine-insnsโ the max number of instructions the RTL combiner tries to combine ๐งinteger-share-limitโ small integer constants can use a shared data structure, which cuts down on the compiler's memory usage and speeds it up ๐ This sets the max value of a shared integer constant ๐ขssp-buffer-sizeโ the minimum size of buffers (aka arrays) that get stack smashing protection when-fstack-protectionis used ๐ก๏ธ- Before Ubuntu 10.10 this default was
"8". Currently it's"4", so more functions get protected by the stack protector ๐
- Before Ubuntu 10.10 this default was
min-size-for-stack-sharingโ the minimum size of variables taking part in stack slot sharing when not optimizing ๐ฅกmax-jump-thread-duplication-stmtsโ the max number of statements allowed in a block that needs to be duplicated when threading jumps ๐งตmax-fields-for-field-sensitiveโ the max number of fields in a structure that gets treated in a field sensitive manner during pointer analysis ๐ฌprefetch-latencyโ an estimate of the average number of instructions executed before a prefetch finishes โฑ๏ธ The distance prefetched ahead is proportional to this constant. Increasing it may also mean fewer streams get prefetched (seesimultaneous-prefetches) ๐simultaneous-prefetchesโ the max number of prefetches that can run at the same time ๐โโ๏ธ๐จl1-cache-line-sizeโ the size of a cache line in the L1 data cache, in bytes ๐งl1-cache-sizeโ the size of the L1 data cache, in kilobytes ๐l2-cache-sizeโ the size of the L2 data cache, in kilobytes ๐ฉทprefetch-dynamic-stridesโ controls whether the loop array prefetch pass should issue software prefetch hints for strides that are non-constant ๐ In some cases that's beneficial, but since the stride isn't constant, it can be hard to predict when there's a clear benefit โจ- Set to
1if prefetch hints should be issued for non-constant strides. - Set to
0if prefetch hints should be issued only for strides that are known to be constant and belowprefetch-minimum-stride.
- Set to
prefetch-minimum-strideโ the minimum constant stride, in bytes, needed before prefetch hints start getting used ๐ฆ If the stride is less than this threshold, prefetch hints won't be issued ๐ซถ
Okay so this one is lowkey the most important bit for chips with hardware prefetchers ๐ฅ, because the hardware and software prefetchers can totally clash ๐. If the hardware prefetcher has a max stride it can handle, put that number here so the software prefetchers get used properly โจ.
A value of -1 means there's no threshold at all, so prefetch hints can be issued for any constant stride ๐ฆ.
This setting only matters for strides that are known and constant ๐ .
loop-interchange-max-num-stmts
The max number of statements in a loop that can be interchanged ๐.
loop-interchange-stride-ratio
The minimum ratio between the strides of two loops for interchange to be worth it ๐.
min-insn-to-prefetch-ratio
The minimum ratio between the number of instructions and the number of prefetches needed to turn on prefetching in a loop ๐ง.
prefetch-min-insn-to-mem-ratio
The minimum ratio between the number of instructions and the number of memory references needed to turn on prefetching in a loop ๐.
use-canonical-types
Whether the compiler uses the "canonical" type system โจ. It should always be 1, because that uses a more efficient internal mechanism for comparing types in C++ and Objective-C++ ๐. But if bugs in the canonical type system are causing compilation failures, set this to 0 to turn canonical types off ๐ญ.
switch-conversion-max-branch-ratio
Switch initialization conversion won't create arrays bigger than switch-conversion-max-branch-ratio times the number of branches in the switch ๐.
max-partial-antic-length
The max length of the partial antic set computed during tree partial redundancy elimination (-ftree-pre) when optimizing at -O3 and above ๐ฆ. For some kinds of source code this enhanced PRE can run away and eat all the memory on the host machine ๐. This caps the length of those sets so it can't happen. Setting it to 0 allows unlimited set length, so proceed with caution bestie โ ๏ธ.
rpo-vn-max-loop-depth
The max loop depth that gets value-numbered optimistically ๐ธ. When the limit hits, the innermost rpo-vn-max-loop-depth loops and the outermost loop in the loop nest get value-numbered optimistically, and the remaining ones don't ๐ง.
sccvn-max-alias-queries-per-access
The max number of alias-oracle queries we make when hunting for redundancies in loads and stores ๐. If this limit is hit, the search is aborted and that load or store is not considered redundant. The number of queries is algorithmically limited to the number of stores on all paths from the load to the function entry ๐ซถ.
ira-max-loops-num
IRA uses regional register allocation by default ๐ . If a function has more loops than this parameter, only the given number of the most frequently-executed loops form regions for regional register allocation ๐.
ira-max-conflict-table-size
IRA has a sophisticated algorithm to compress the conflict table, but huge functions can still need excessive memory ๐ฉ. If the conflict table for a function could be more than this many MB, the register allocator switches to a faster, simpler, and lower-quality algorithm that doesn't build a pseudo-register conflict table ๐.
ira-loop-reserved-regs
IRA can evaluate more accurate register pressure in loops when deciding whether to move loop invariants (see -O3) ๐. The number of available registers reserved for other purposes is given by this parameter. The default is the best value found from numerous experiments ๐ฅ.
lra-inheritance-ebb-probability-cutoff
LRA tries to reuse values reloaded into registers in subsequent insns, and this is called inheritance ๐ฆ. EBB is the region used for this optimization. The parameter sets the minimal fall-through edge probability, in percentage, used to add a BB to the inheritance EBB in LRA โจ. The default was chosen from numerous runs of SPEC2000 on x86-64 ๐.
loop-invariant-max-bbs-in-loop
Loop invariant motion can be very expensive, both in compilation time and in compile-time memory, with very large loops ๐ต. Loops with more basic blocks than this parameter won't get loop invariant motion performed on them ๐ โโ๏ธ.
loop-max-datarefs-for-datadeps
Building data dependencies is expensive for very large loops ๐. This limits the number of data references in loops that get considered for data dependence analysis. These large loops are not handled by the optimizations that use loop data dependencies ๐ซถ.
max-vartrack-size
Sets the max number of hash table slots used during variable tracking dataflow analysis of any function ๐ง. If this limit is exceeded with variable tracking at assignments enabled, analysis for that function is retried without it, after removing all debug insns from the function ๐ธ. If the limit is exceeded even without debug insns, var tracking analysis is completely disabled for the function ๐ญ. Setting the parameter to zero makes it unlimited ๐.
max-vartrack-expr-depth
Sets the max number of recursion levels when mapping variable names or debug temporaries to value expressions ๐. This trades compilation time for more complete debug information ๐. If it's set too low, value expressions that are available and could be represented in debug information may end up not being used ๐. Setting it higher may let the compiler find more complex debug expressions, but compile time and memory use may grow ๐.
max-debug-marker-count
Sets a threshold on the number of debug markers (e.g. begin stmt markers) to avoid complexity explosion at inlining or when expanding to RTL ๐ . If a function has more such gimple stmts than the limit, they get dropped from the inlined copy of the function, and from its RTL expansion ๐ฆ.
min-nondebug-insn-uid
Use uids starting at this parameter for nondebug insns โจ. The range below it is reserved exclusively for debug insns created by -fvar-tracking-assignments. Debug insns may still get (non-overlapping) uids above it if that reserved range runs out ๐.
ipa-sra-ptr-growth-factor
IPA-SRA only replaces a pointer to an aggregate with one or more new parameters when their cumulative size is less than or equal to ipa-sra-ptr-growth-factor times the size of the original pointer parameter ๐.
ipa-sra-max-replacements
The max pieces of an aggregate that IPA-SRA tracks ๐ธ. That means it's also the max number of replacements of a formal parameter ๐.
sra-max-scalarization-size-Ospeed and sra-max-scalarization-size-Osize
The two Scalar Reduction of Aggregates passes (SRA and IPA-SRA) aim to replace scalar parts of aggregates with uses of independent scalar variables ๐ง. These two parameters control the max size, in storage units, of an aggregate that's considered for replacement when compiling for speed (sra-max-scalarization-size-Ospeed) or for size (sra-max-scalarization-size-Osize) respectively ๐ฅ.
sra-max-propagations
The max number of artificial accesses that Scalar Replacement of Aggregates (SRA) will track per local variable, so copy propagation can happen ๐ฆ.
tm-max-aggregate-size
When making copies of thread-local variables in a transaction, this sets the size in bytes after which variables get saved with the logging functions instead of save/restore code sequence pairs ๐. This only applies when using -fgnu-tm ๐
.
graphite-max-nb-scop-params
To avoid exponential effects in the Graphite loop transforms, the number of parameters in a Static Control Part (SCoP) is bounded ๐. A value of 0 can be used to lift the bound ๐. A variable whose value is unknown at compile time and defined outside a SCoP is a parameter of that SCoP โจ.
loop-block-tile-size
Loop blocking or strip mining transforms, enabled with -floop-block or -floop-strip-mine, strip mine each loop in the loop nest by a given number of iterations ๐. The strip length can be changed using this parameter ๐.
ipa-cp-value-list-size
IPA-CP tries to track all possible values and types passed to a function's parameter so it can propagate them and perform devirtualization ๐ง. This is the max number of values and types it stores per formal parameter of a function ๐.
ipa-cp-eval-threshold
IPA-CP calculates its own score of cloning profitability heuristics, and it performs those cloning opportunities whose scores exceed ipa-cp-eval-threshold ๐ฅ.
ipa-cp-max-recursive-depth
Max depth of recursive cloning for a self-recursive function ๐ธ.
ipa-cp-min-recursive-probability
Recursive cloning only happens when the probability of the call being executed exceeds this parameter ๐ฆ.
ipa-cp-recursion-penalty
Percentage penalty that recursive functions receive when they're evaluated for cloning ๐ฌ.
ipa-cp-single-call-penalty
Percentage penalty that functions containing a single call to another function receive when they're evaluated for cloning ๐ซถ.
ipa-max-agg-items
IPA-CP can also propagate a number of scalar values passed in an aggregate ๐. ipa-max-agg-items controls the max number of those values per parameter โจ.
ipa-cp-loop-hint-bonusโ okay so, when IPA-CP realizes a cloning candidate would make a loop's iteration count known, it slaps a bonus ofipa-cp-loop-hint-bonusonto that candidate's profitability score ๐ โจipa-max-aa-stepsโ while IPA-CP pokes around in function bodies, it uses alias analysis to keep track of values pointed to by function parameters ๐ To avoid wasting ages on huge functions, it gives up and treats all memory as clobbered after checkingipa-max-aa-stepsstatements that modify memory ๐ipa-max-switch-predicate-boundsโ the max number of boundary endpoints in a switch statement's case ranges ๐ If a switch goes over this limit, IPA-CP skips building the cloning cost predicate for that switch's default case. (That predicate is what estimates the cloning benefit, btw ๐ง)ipa-max-param-expr-opsโ IPA-CP checks conditional statements that reference a function parameter to figure out the cloning benefit for a certain constant value ๐ฆ But if a parameter expression has more operations thanipa-max-param-expr-ops, it's labelled as too complicated and IPA analysis just doesn't touch it ๐lto-partitionsโ the desired number of partitions made during WHOPR compilation ๐ธ It should be more than the number of CPUs you're compiling with โจlto-min-partitionโ the size of the smallest allowed WHOPR partition, measured in estimated instructions ๐ This stops tiny programs from getting chopped into way too many partitions, which would be a huge waste of effort ๐ซถlto-max-partitionโ the size of the biggest WHOPR partition, measured in estimated instructions ๐ It sets an upper bound on how large any individual partition can get. It's only meant to be used with balanced partitioning, so don't go wild with it ๐lto-max-streaming-parallelismโ the max number of parallel processes that can be used for LTO streaming ๐cxx-max-namespaces-for-diagnostic-helpโ the max number of namespaces GCC will check for suggestions when a C++ name lookup fails for an identifier ๐ฅsink-frequency-thresholdโ the highest relative execution frequency (in percent) of a target block, compared to the statement's original block, that still lets a statement get sunk ๐ง Bigger numbers mean more aggressive sinking โญ Statements with memory operands get a small positive nudge, since sinking those is even more profitable ๐max-stores-to-sinkโ the max number of conditional store pairs that can be sunk ๐ Set it to0if either vectorization (-ftree-vectorize) or if-conversion (-ftree-loop-if-convert) is turned off ๐ โโ๏ธcase-values-thresholdโ the smallest number of different values where a jump table beats a tree of conditional branches ๐ฆ If it's0, the machine's default gets used ๐ธjump-table-max-growth-ratio-for-sizeโ the max code size growth ratio (in percent) when expanding into a jump table ๐ This one kicks in when you're optimizing for size ๐jump-table-max-growth-ratio-for-speedโ the max code size growth ratio (in percent) when expanding into a jump table ๐ฅ This one kicks in when you're optimizing for speed ๐๏ธtree-reassoc-widthโ the max number of instructions that can execute in parallel in a reassociated tree ๐ If it has a nonzero value, it overrides the target-dependent heuristics that would normally be used by default ๐sched-pressure-algorithmโ picks one of the two available implementations of-fsched-pressure๐ง Here's the tea:- Algorithm 1 โ the original implementation ๐ฐ๏ธ It's the more likely of the two to stop instructions from getting reordered ๐
- Algorithm 2 โ designed as a compromise between the pretty conservative vibes of algorithm 1 and the rather aggressive approach of the default scheduler ๐ข It leans harder on having a regular register file and accurate register pressure classes ๐ซถ
- The default choice depends on the target ๐ฏ
- For more details, check out
haifa-sched.cin the GCC sources ๐
max-slsr-cand-scanโ the max number of existing candidates considered when hunting for a basis for a new straight-line strength reduction candidate ๐asan-globalsโ turns on buffer overflow detection for global objects ๐ This protection is on by default when you use-fsanitize=address๐ To turn off global objects protection, use--param asan-globals=0๐ โโ๏ธasan-stackโ turns on buffer overflow detection for stack objects ๐ฅ It's on by default with-fsanitize=addressโจ To disable stack protection, use--param asan-stack=0๐asan-instrument-readsโ turns on buffer overflow detection for memory reads ๐ Also on by default with-fsanitize=address๐ธ To turn off memory reads protection, use--param asan-instrument-reads=0๐ซถasan-instrument-writesโ turns on buffer overflow detection for memory writes โ๏ธ It's on by default when using-fsanitize=address๐ฆ To disable memory writes protection, use--param asan-instrument-writes=0๐ โโ๏ธasan-memintrinโ turns on detection for built-in functions ๐งฉ On by default with-fsanitize=address๐ To disable built-in functions protection, use--param asan-memintrin=0๐ซasan-use-after-returnโ turns on detection of use-after-return ๐ต๏ธโโ๏ธ It's enabled by default with the-fsanitize=addressoption ๐ฅ To turn it off, use--param asan-use-after-return=0๐
Heads up, bestie: by default this check is disabled at run time ๐ญ To turn it on, add"detect_stack_use_after_return=1"to theASAN_OPTIONSenvironment variable ๐ซถ
asan-instrumentation-with-call-thresholdโ if the function being instrumented has a number of memory accesses greater than or equal to this value, ASan uses callbacks instead of inline checks ๐ To turn off inline code completely, use--param asan-instrumentation-with-call-threshold=0๐งuse-after-scope-direct-emission-thresholdโ if a local variable is smaller than or equal to this many bytes, shadow memory gets poisoned (or unpoisoned) directly instead of going through run-time callbacks โกmax-fsm-thread-path-insnsโ the max number of instructions copied when duplicating blocks on a finite state automaton jump thread path ๐งตmax-fsm-thread-lengthโ the max number of basic blocks on a finite state automaton jump thread path ๐ค๏ธmax-fsm-thread-pathsโ the max number of new jump thread paths to create for a finite state automaton ๐parloops-chunk-sizeโ the chunk size of the omp schedule for loops parallelized by parloops ๐ฐparloops-scheduleโ the schedule type of the omp schedule for loops parallelized by parloops ๐๏ธ The options arestatic,dynamic,guided,auto, orruntime๐parloops-min-per-threadโ the minimum number of iterations per thread for an innermost parallelized loop where the parallel version is preferred over the single-threaded one ๐งต For a parallelized loop nest, the minimum number of iterations of the outermost loop per thread is two ๐max-ssa-name-query-depthโ the max recursion depth when querying properties of SSA names in things like fold routines ๐ One level of recursion means following one use-def chain ๐hsa-gen-debug-storesโ enables emitting special debug stores inside HSA kernels, which the libgomp plugin then reads and reports ๐ It's disabled by default, so use--param hsa-gen-debug-stores=1to switch it on ๐ซถmax-speculative-devirt-maydefsโ the max number of may-defs analyzed while looking for a must-def that specifies the dynamic type of an object making a virtual call we might speculatively devirtualize ๐max-vrp-switch-assertionsโ the max number of assertions added along the default edge of a switch statement during VRP ๐งunroll-jam-min-percentโ the minimum percentage of memory references that have to get optimized away before unroll-and-jam is considered profitable ๐unroll-jam-max-unrollโ the max number of times the outer loop can be unrolled by unroll-and-jam ๐max-rtl-if-conversion-unpredictable-costโ the max permissible cost for the sequence the RTL if-conversion pass would generate for a branch that's considered unpredictable ๐ฒmax-variable-expansions-in-unrollerโ if-fvariable-expansion-in-unrolleris used, this is the max number of times an individual variable gets expanded during loop unrolling ๐ฑtracer-min-branch-probability-feedbackโ stop growing forward if the probability of the best edge is below this threshold (in percent) ๐ It's used when profile feedback is available ๐partial-inlining-entry-probabilityโ the max probability (in percent, relative to the function's entry BB) of the entry BB of a split region that still lets partial inlining happen ๐งฉmax-tracked-strlensโ the max number of strings the strlen optimization pass will track lengths for ๐gcse-after-reload-partial-fractionโ the threshold ratio for performing partial redundancy elimination after reload ๐gcse-after-reload-critical-fractionโ the threshold ratio of the critical edges execution count that allows redundancy elimination after reload โ๏ธmax-loop-header-insnsโ the max number of insns in a loop header that the copy loop headers pass is allowed to duplicate ๐งพvect-epilogues-nomaskโ enables loop epilogue vectorization using a smaller vector size ๐ชslp-max-insns-in-bbโ the max number of instructions in a basic block that gets considered for SLP vectorization ๐งบavoid-fma-max-bitsโ the max number of bits for which GCC avoids creating FMAs ๐ซโ๏ธsms-loop-average-count-thresholdโ okay so this is a threshold on the average loop count that the swing modulo scheduler pays attention to ๐sms-dfa-historyโ the number of cycles the swing modulo scheduler looks at when it's checking for conflicts using DFA ๐max-inline-insns-recursive-autoโ the max number of instructions a non-inline function can grow to through recursive inlining ๐ธgraphite-allow-codegen-errorsโ decides whether codegen errors should be ICEs when-fcheckingis on ๐sms-max-ii-factorโ a factor for tuning the upper bound the swing modulo scheduler uses when it schedules a loop โจlra-max-considered-reload-pseudosโ the max number of reload pseudos that get considered while spilling a non-reload pseudo ๐งmax-pow-sqrt-depthโ the maximum depth of sqrt chains you can use when synthesizing exponentiation by a real constant ๐ฆmax-dse-active-local-storesโ the maximum number of active local stores in RTL dead store elimination ๐ซถasan-instrument-allocasโ enables asan allocas/VLAs protection ๐ก๏ธmax-iterations-computation-costโ the bound on how expensive an expression can be when computing the number of iterations ๐max-isl-operationsโ the maximum number of isl operations, where0means unlimited ๐graphite-max-arrays-per-scopโ the maximum number of arrays per scop ๐max-vartrack-reverse-op-sizeโ the max size of a loc list where reverse ops get added, abbreviated as "max." in the original ๐tracer-dynamic-coverage-feedbackโ the percentage of a function, weighted by execution frequency, that trace formation has to cover. This one is used when profile feedback is available ๐max-inline-recursive-depth-autoโ the maximum depth of recursive inlining for non-inline functions ๐fsm-scale-path-stmtsโ a scale factor applied to the number of statements in a threading path when you compare it to the number of (scaled) blocks ๐งฎfsm-maximum-phi-argumentsโ the max number of arguments a PHI can have before the FSM threader stops trying to thread through its block ๐ซuninit-control-dep-attemptsโ the max number of nested calls used to search for control dependencies during uninitialized variable analysis ๐sra-max-scalarization-size-Osizeโ the max size, in storage units, of an aggregate that should be considered for scalarization when you're compiling for size ๐ฆfsm-scale-path-blocksโ a scale factor applied to the number of blocks in a threading path when you compare it to the number of (scaled) statements ๐งsched-autopref-queue-depthโ a control flag for the hardware autoprefetcher scheduler model. It sets how many lookahead cycles the model peeks into, and at' 'it only enables the instruction sorting heuristic ๐ทloop-versioning-max-inner-insnsโ the max number of instructions an inner loop can have before the loop versioning pass decides it's too big to copy ๐ซงloop-versioning-max-outer-insnsโ the max number of instructions an outer loop can have before the loop versioning pass decides it's too big to copy. Any instructions in inner loops that directly benefit from versioning don't count toward that total ๐ssa-name-def-chain-limitโ the max number of SSA_NAME assignments to follow when figuring out a property of a variable, like its value. This caps how many iterations or recursive calls GCC makes while optimizing certain statements or checking whether they're valid before it issues diagnostics ๐store-merging-max-sizeโ the max size of a single store merging region, in bytes ๐hash-table-verification-limitโ the number of elements that get hash table verification for each element you search for ๐max-find-base-term-valuesโ the max number of VALUEs handled during a singlefind_base_termcall ๐ฏanalyzer-max-enodes-per-program-pointโ the max number of exploded nodes per program point within the analyzer. Once that's hit, analysis of that point stops ๐analyzer-min-snodes-for-call-summaryโ the min number of supernodes within a function before the analyzer will think about summarizing its effects at call sites ๐analyzer-max-recursion-depthโ the max number of times a callsite can show up in a call stack within the analyzer. Once that's reached, analysis of a call that would recurse deeper is terminated ๐ช๏ธgimple-fe-computed-hot-bb-thresholdโ the number of executions of a basic block that counts as hot. This parameter is only used in GIMPLE FE ๐ฅanalyzer-bb-explosion-factorโ the max number of 'after supernode' exploded nodes per supernode within the analyzer, before analysis gets terminated ๐ซ
Also, these next ones are only for AArch64 targets ๐ฆ:
aarch64-sve-compare-costsโ when you're vectorizing for SVE, this considers using "unpacked" vectors for smaller elements, and it uses the cost model to pick the cheapest approach. It also uses the cost model to choose between SVE and Advanced SIMD vectorization ๐
Using unpacked vectors means storing smaller elements in larger containers, and accessing elements with extending loads and truncating stores.
aarch64-float-recp-precisionโ the number of Newton iterations used to calculate the reciprocal for the float type. The precision of division is proportional to this param when division approximation is enabled. The default value is1. ๐aarch64-double-recp-precisionโ the number of Newton iterations used to calculate the reciprocal for the double type. The precision of division is proportional to this param when division approximation is enabled. The default value is2. ๐aarch64-autovec-preferenceโ forces an ISA selection strategy for auto-vectorization. It accepts values from0to4, inclusive. ๐0โ use the default heuristics.1โ use only Advanced SIMD for auto-vectorization.2โ use only SVE for auto-vectorization.3โ use both Advanced SIMD and SVE. Prefer Advanced SIMD when the costs are deemed equal.4โ use both Advanced SIMD and SVE. Prefer SVE when the costs are deemed equal.
The default value is 0.
โจ Program Instrumentation Options โจ
okay so GCC has a bunch of command-line options that tell it to add run-time instrumentation to the code it normally generates ๐ง Instrumentation can be for collecting profiling stats so you can find program hot spots, doing code coverage analysis, or doing profile-guided optimizations ๐. It's also used for run-time checking that catches programming errors like invalid pointer dereferences or out-of-bounds array accesses, and it helps guard against deliberately hostile attacks like stack smashing or C++ vtable hijacking ๐ก๏ธ. There's also a general hook that can be used to implement other forms of tracing or function-level instrumentation for debugging or program analysis ๐
-p,-pgโ these generate extra code that writes profile information suitable for the analysis programprof(for-p) orgprof(for-pg). You have to use this option when compiling the source files you want data about, and you also have to use it when linking ๐
You can use the function attribute "no_instrument_function" to skip profiling of individual functions when compiling with these options ๐
-fprofile-arcsโ adds code so that program flow arcs get instrumented. While the program runs, it records how many times each branch and call gets executed, and how many times each one is taken or returns ๐ธ. On targets that support constructors with priority support, profiling properly handles constructors, destructors, and C++ constructors (and destructors) of classes that are used as a type of a global variable ๐ซถ
When the compiled program exits, it saves this data to a file called auxname.gcda for each source file ๐พ. The data can be used for profile-directed optimizations (-fbranch-probabilities) or for test coverage analysis (-ftest-coverage). Each object file's auxname is generated from the name of the output file, if one is explicitly specified and it isn't the final executable. Otherwise it's the basename of the source file. In both cases, any suffix gets removed. For example, you'd get foo.gcda for input file dir/foo.c, or dir/foo.gcda for output file specified as -o dir/foo.o ๐ฆ
--coverageโ this is for compiling and linking code that's instrumented for coverage analysis. It's a synonym for-fprofile-arcs-ftest-coverage(when compiling) and-lgcov(when linking). Check out the docs for those options for more details ๐- Compile the source files with
-fprofile-arcsplus optimization and code generation options. For test coverage analysis, add the extra-ftest-coverageoption. You don't need to profile every source file in a program ๐ท - Compile the source files additionally with
-fprofile-abs-pathto create absolute path names in the.gcnofiles. This letsgcovfind the correct sources in projects where compilations happen with different working directories ๐บ๏ธ - Link your object files with
-lgcovor-fprofile-arcs(the latter implies the former) ๐ - Run the program on a representative workload to generate the arc profile information. You can do this any number of times. You can run concurrent instances of your program, and as long as the file system supports locking, the data files will be correctly updated ๐โโ๏ธ. Unless a strict ISO C dialect option is in effect,
"fork"calls are detected and correctly handled without double counting ๐ด - For profile-directed optimizations, compile the source files again with the same optimization and code generation options plus
-fbranch-probabilities๐ - For test coverage analysis, use
gcovto produce human readable information from the.gcnoand.gcdafiles. Check thegcovdocumentation for further information ๐
- Compile the source files with
With -fprofile-arcs, GCC builds a program flow graph for every function in your program, then finds a spanning tree for it ๐ฆ. Only the arcs that are not on that tree need instrumenting, so the compiler just adds code to count how many times those arcs run ๐. When an arc is the only exit or only entrance to a block, the counting code can go right inside that block. Otherwise GCC has to make a brand new basic block just to hold the instrumentation ๐ง
-ftest-coverageโ Produces a notes file that thegcovcode-coverage utility can read to show program coverage ๐. Each source file's note file is calledauxname.gcno. For whatauxnamemeans and how to generate test coverage data, check out-fprofile-arcsabove ๐. Coverage data lines up with your source files more closely if you do not optimize ๐.-fprofile-abs-pathโ Automatically converts relative source file names into absolute path names inside the.gcnofiles ๐บ๏ธ. This helpsgcovfind the correct sources in projects that compile from different working directories ๐ซถ.-fprofile-dir=pathโ Sets the directory where profile data files get searched for, topath๐. This only affects the profile data made by-fprofile-generate,-ftest-coverage, and-fprofile-arcs, plus the data used by-fprofile-use,-fbranch-probabilities, and their related options. Both absolute and relative paths work. By default GCC uses the current directory, so the profile data file lands in the same directory as the object file. To stop file names from clashing, if the object file name isn't an absolute path, GCC mangles the absolute path of thesourcename.gcdafile and uses that as the name of a.gcdafile. See the similar option-fprofile-note.
When an executable runs in a massive parallel environment, it's recommended to save profiles to different folders ๐. You can do that with variables in path that get exported at run-time:
%pโ process ID.%q{VAR}โ value of environment variableVAR.
-fprofile-generate,-fprofile-generate=pathโ Turns on the options usually used for instrumenting an application, so it produces a profile for later recompilation with profile feedback based optimization ๐ฅ. You must use-fprofile-generateboth when compiling and when linking your program ๐จ. The following options are enabled:-fprofile-arcs,-fprofile-values,-finline-functions, and-fipa-bit-cp. Ifpathis specified, GCC looks at that path to find the profile feedback data files. See-fprofile-dir. To optimize the program based on the collected profile information, use-fprofile-use.-fprofile-note=pathโ Ifpathis specified, GCC saves the.gcnofile into that location ๐ฆ. If you combine this with multiple source files, the.gcnofile will get overwritten ๐ฌ.-fprofile-prefix-path=pathโ Use this withprofile-generate=profile_dirandprofile-use=profile_dirto tell GCC where the base directory of your built source tree is ๐ณ. By default,profile_dirholds files with mangled absolute paths of all object files in the built project. That's not ideal when the directory used to build the instrumented binary is different from the one used to build the profile-optimized binary, because the profile data won't be found during the optimized build ๐ญ. In those setups,-fprofile-prefix-path=pathwithpathpointing to the base directory of the build strips the irrelevant part of the path and keeps every file name relative to the main build directory โจ.-fprofile-update=methodโ Changes the update method for an application instrumented for profile feedback based optimization ๐. Themethodargument should be one ofsingle,atomic, orprefer-atomic.singleis great for single-threaded applications, whileatomicprevents profile corruption by emitting thread-safe code ๐ก๏ธ. Usingprefer-atomicbecomesatomicwhen the target supports it, orsingleotherwise. The GCC driver automatically selectsprefer-atomicwhen-pthreadis in the command line ๐งต.
Warning: When an application doesn't properly join all threads (or creates a detached thread), a profile file can still get corrupted ๐.
-fprofile-filter-files=regexโ Instruments only functions from files whose names match any of the regular expressions, separated by a semicolon ๐ฏ. For example,-fprofile-filter-files=main.c;module.*.cwill instrument onlymain.cand all C files starting with 'module' ๐ .-fprofile-exclude-files=regexโ Instruments only functions from files where the names do not match all the regular expressions, separated by a semicolon ๐ . For example,-fprofile-exclude-files=/usr/*will stop instrumentation of every file located in the/usr/folder ๐ซฃ.-fprofile-reproducible=[multithreaded|parallel-runs|serial]โ Controls how reproducible the profile gathered by-fprofile-generateis ๐. This lets you rebuild a program with the same outcome, which is super useful for things like distribution packages ๐ฆ.serialโ The profile gathered by-fprofile-generateis reproducible as long as the trained program behaves the same on every invocation of the train run, it is not multi-threaded, and profile data streaming always happens in the same order ๐ง. Note that profile streaming happens at the end of the program run, but also before theforkfunction is invoked.parallel-runsโ The collected profile stays reproducible no matter what order the data gets streamed intogcdafiles ๐. This makes it possible to run multiple instances of the instrumented program in parallel (such as withmake -j), but it reduces the quality of the gathered data, particularly for indirect call profiling ๐ต.
Heads up: it's pretty common for execution counts in some parts of a program to depend on things like the length of temporary file names or memory space randomization (which can affect hash-table collision rates) ๐ฒ. Those non-reproducible parts can be annotated with the no_instrument_function function attribute. You can use gcov-dump with -l to dump the gathered data and verify that it's actually reproducible ๐.
-fsanitize=addressโ Enables AddressSanitizer, a fast memory error detector ๐. Memory access instructions get instrumented to catch out-of-bounds and use-after-free bugs ๐. This option enables-fsanitize-address-use-after-scope. For more details, seehttps://github.com/google/sanitizers/wiki/AddressSanitizer. The run-time behavior can be influenced with theASAN_OPTIONSenvironment variable ๐๏ธ. When it's set tohelp=1, the available options get shown at startup of the instrumented program. For a list of supported options, seehttps://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags. This option cannot be combined with-fsanitize=thread.-fsanitize=kernel-addressโ Enables AddressSanitizer for the Linux kernel ๐ง. For more details, seehttps://github.com/google/kasan/wiki.-fsanitize=pointer-compareโ Instruments comparison operations (<,<=,>,>=) with pointer operands ๐. This option must be combined with either-fsanitize=kernel-addressor-fsanitize=address. It cannot be combined with-fsanitize=thread. Note: by default the check is disabled at run time ๐. To turn it on, adddetect_invalid_pointer_pairs=2to theASAN_OPTIONSenvironment variable. Usingdetect_invalid_pointer_pairs=1only detects invalid operations when both pointers are non-null.-fsanitize=pointer-subtractโ Instruments subtraction with pointer operands ๐งฎ. This option must be combined with either-fsanitize=kernel-addressor-fsanitize=address. It cannot be combined with-fsanitize=thread. Note: by default the check is disabled at run time ๐. To turn it on, adddetect_invalid_pointer_pairs=2to theASAN_OPTIONSenvironment variable. Usingdetect_invalid_pointer_pairs=1only detects invalid operations when both pointers are non-null.-fsanitize=threadโ Enables ThreadSanitizer, a fast data race detector ๐งต. Memory access instructions get instrumented to catch data race bugs. For more details, seehttps://github.com/google/sanitizers/wiki#threadsanitizer. The run-time behavior can be influenced with theTSAN_OPTIONSenvironment variable. For a list of supported options, seehttps://github.com/google/sanitizers/wiki/ThreadSanitizerFlags. This option cannot be combined with-fsanitize=addressor-fsanitize=leak.
Note: sanitized atomic builtins cannot throw exceptions when operating on invalid memory addresses with non-call exceptions (-fnon-call-exceptions) ๐ซ.
-fsanitize=leakโ Enables LeakSanitizer, a memory leak detector ๐ง. This option only matters when linking executables, and only if the executable is linked against a library that overridesmallocand other allocator functions. For more details, seehttps://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer. The run-time behavior can be influenced with theLSAN_OPTIONSenvironment variable. This option cannot be combined with-fsanitize=thread.-fsanitize=undefinedโ Enables UndefinedBehaviorSanitizer, a fast undefined behavior detector ๐. Various computations get instrumented to catch undefined behavior at runtime. Seehttps://clang.llvm.org/docs/UndefinedBehaviorSanitizer.htmlfor more details. The run-time behavior can be influenced with theUBSAN_OPTIONSenvironment variable. The current suboptions are:-fsanitize=shiftโ Enables checking that the result of a shift operation isn't undefined ๐ซฃ. What counts as undefined differs slightly between C and C++, and between ISO C90 and C99, and so on. This option has two suboptions,-fsanitize=shift-baseand-fsanitize=shift-exponent.-fsanitize=shift-exponentโ Enables checking that the second argument of a shift operation isn't negative and is smaller than the precision of the promoted first argument ๐ง.
-fsanitize=shift-baseโ okay so when the second argument of a shift is in range, this checks that the shift result isn't undefined ๐ Heads up: what counts as undefined is slightly different between C and C++, and between ISO C90 and C99, etc. ๐ธ-fsanitize=integer-divide-by-zeroโ catches integer division by zero ๐ โโ๏ธ and also the"INT_MIN / -1"division, which is a sneaky one ๐-fsanitize=unreachableโ this one is giving "you should never be here" energy ๐ง With it on, the compiler swaps the"__builtin_unreachable"call for a diagnostics message call instead. Reaching that"__builtin_unreachable"call is undefined, so the behavior is undefined. ๐-fsanitize=vla-boundโ checks that the size of a variable length array is positive ๐โจ-fsanitize=nullโ pointer checking, bestie ๐ซถ Apps built with this will throw an error when they try to dereference aNULLpointer, when a reference (possibly an rvalue reference) gets bound to aNULLpointer, or when a method gets invoked on an object pointed to by aNULLpointer.-fsanitize=returnโ return statement checking ๐ Programs built with this will throw an error when the end of a non-void function gets reached without actually returning a value. This option works in C++ only.-fsanitize=signed-integer-overflowโ signed integer overflow checking ๐ฅ It checks that the result of+,*, and both unary and binary-doesn't overflow in signed arithmetic. Also, integer promotion rules totally count here! So this is not an overflow:
signed char a = SCHAR_MAX;
a++;
-fsanitize=boundsโ array bounds instrumentation, so various out of bounds accesses get detected ๐ฆ Flexible array members, flexible array member-like arrays, and initializers of variables with static storage are not instrumented.-fsanitize=bounds-strictโ the stricter version ๐ Most out of bounds accesses get detected, including flexible array members and flexible array member-like arrays. Initializers of variables with static storage are still not instrumented.-fsanitize=alignmentโ checks pointer alignment when they're dereferenced ๐ง It also checks when a reference is bound to an insufficiently aligned target, or when a method or constructor is invoked on an insufficiently aligned object.-fsanitize=object-sizeโ instruments memory references using the"__builtin_object_size"function ๐ Various out of bounds pointer accesses get detected.-fsanitize=float-divide-by-zeroโ detects floating-point division by zero ๐งฎ Unlike other similar options, this one is not turned on by-fsanitize=undefined, because floating-point division by zero can be a totally legit way to get infinities and NaNs. โญ-fsanitize=float-cast-overflowโ floating-point type to integer conversion checking ๐ It checks that the result of the conversion doesn't overflow. Unlike other similar options, this is not turned on by-fsanitize=undefined. Also, this option does not work well with"FE_INVALID"exceptions enabled, so keep that in mind ๐-fsanitize=nonnull-attributeโ instruments calls to check that null values aren't passed to arguments marked as requiring a non-null value by the"nonnull"function attribute ๐-fsanitize=returns-nonnull-attributeโ instruments return statements in functions marked with the"returns_nonnull"function attribute ๐ This catches functions returning null values when they shouldn't.-fsanitize=boolโ instruments loads fromboolโ If a value other than 0/1 gets loaded, a run-time error is issued.-fsanitize=enumโ instruments loads from an enum type ๐ธ If a value outside the range of values for the enum type gets loaded, a run-time error is issued.-fsanitize=vptrโ C++ vibes ๐ It instruments C++ member function calls, member accesses, and some conversions between pointers to base and derived classes, so it can verify the referenced object has the correct dynamic type.-fsanitize=pointer-overflowโ instruments pointer arithmetic ๐งโโ๏ธ If the pointer arithmetic overflows, a run-time error is issued.-fsanitize=builtinโ instruments arguments to selected builtin functions ๐ If an invalid value gets passed to one of those arguments, a run-time error is issued. For example, passing0as the argument to"__builtin_ctz"or"__builtin_clz"invokes undefined behavior, and this option diagnoses it.
While -ftrapv causes traps for signed overflows to be emitted, -fsanitize=undefined gives a diagnostic message instead ๐ฆ Quick note: this currently works only for the C family of languages.
-fno-sanitize=allโ disables all previously enabled sanitizers ๐งน-fsanitize=allis not allowed, though, since some sanitizers can't be used together. ๐ โโ๏ธ-fasan-shadow-offset=numberโ forces GCC to use a custom shadow offset in AddressSanitizer checks ๐งช It's useful for experimenting with different shadow memory layouts in Kernel AddressSanitizer.-fsanitize-sections=s1,s2,...โ sanitizes global variables in selected user-defined sections ๐simay contain wildcards.-fsanitize-recover[=opts]โ controls the error recovery mode for the sanitizers listed in the comma-separatedoptslist ๐ When recovery is enabled for a sanitizer, it tries to keep running the program like no error happened. That means multiple runtime errors can get reported in one run, and the exit code might say success even though errors were reported. Use-fno-sanitize-recover=if you want to change this: only the first detected error gets reported, and then the program exits with a non-zero exit code.
Right now this only works for -fsanitize=undefined (and its suboptions, except for -fsanitize=unreachable and -fsanitize=return), -fsanitize=float-cast-overflow, -fsanitize=float-divide-by-zero, -fsanitize=bounds-strict, -fsanitize=kernel-address, and -fsanitize=address. For these sanitizers, error recovery is turned on by default, except for -fsanitize=address, where it's still experimental ๐งช You can also use -fsanitize-recover=all and -fno-sanitize-recover=all. The first enables recovery for every sanitizer that supports it, and the second disables recovery for every sanitizer that supports it.
Heads up, bestie: even if recovery is turned on at the compiler side, it also needs to be enabled on the runtime library side. Otherwise the failures are still fatal ๐ญ The runtime library defaults to"halt_on_error=0"for ThreadSanitizer and UndefinedBehaviorSanitizer, while the default for AddressSanitizer is"halt_on_error=1". You can override this by setting the"halt_on_error"flag in the corresponding environment variable.
Syntax without an explicit opts parameter is deprecated ๐ฅ It's equivalent to specifying this opts list:
undefined,float-cast-overflow,float-divide-by-zero,bounds-strict
-fsanitize-address-use-after-scopeโ enables sanitization of local variables so it can catch use-after-scope bugs ๐ต๏ธโโ๏ธ This option sets-fstack-reusetonone.-fsanitize-undefined-trap-on-errorโ tells the compiler to report undefined behavior using"__builtin_trap"instead of a"libubsan"library routine ๐ช The perk is that the"libubsan"library isn't needed and doesn't get linked in, so this is usable even in freestanding environments.-fsanitize-coverage=trace-pcโ enables coverage-guided fuzzing code instrumentation ๐ It inserts a call to"__sanitizer_cov_trace_pc"into every basic block.-fsanitize-coverage=trace-cmpโ enables dataflow guided fuzzing code instrumentation ๐ It inserts these calls:"__sanitizer_cov_trace_cmp1","__sanitizer_cov_trace_cmp2","__sanitizer_cov_trace_cmp4", or"__sanitizer_cov_trace_cmp8"for integral comparisons where both operands are variables"__sanitizer_cov_trace_const_cmp1","__sanitizer_cov_trace_const_cmp2","__sanitizer_cov_trace_const_cmp4", or"__sanitizer_cov_trace_const_cmp8"for integral comparisons where one operand is a constant"__sanitizer_cov_trace_cmpf"or"__sanitizer_cov_trace_cmpd"for float or double comparisons"__sanitizer_cov_trace_switch"for switch statements
-fcf-protection=[full|branch|return|none|check]โ instruments control-flow transfers to boost program security ๐ก๏ธ It checks that target addresses of control-flow transfer instructions (like indirect function calls, function returns, and indirect jumps) are valid, so the flow of control can't get diverted to an unexpected target. This is meant to guard against threats like Return-oriented Programming (ROP), and similar call/jmp-oriented programming (COP/JOP) ๐คbranchโ checks validity of control-flow transfers at indirect branch instructions, i.e.call/jmpinstructions ๐ธreturnโ checks validity at the point of returning from a function ๐ฆfullโ an alias for specifying bothbranchandreturn๐noneโ turns off instrumentation ๐ โโ๏ธcheckโ used for the final link with link-time optimization (LTO) ๐ An error is issued if LTO object files were compiled with different-fcf-protectionvalues. It's ignored at compile time.
The macro __CET__ is defined when -fcf-protection is used โจ Its first bit is set to 1 for the value branch, and its second bit is set to 1 for return. ๐ง
You can also use the nocf_check attribute to tag which functions and calls should be skipped from instrumentation, bestie ๐ซถ it's basically a VIP list for your code โจ
Currently the x86 GNU/Linux target gets an implementation built on Intel Control-flow Enforcement Technology (CET), which works on i686 processors or newer ๐
NOTE: In Ubuntu 19.10 and later versions,-fcf-protectionis enabled by default for C, C++, ObjC, ObjC++, if none of-fno-cf-protectionnor-fcf-protection=*are found ๐ญ
-fstack-protectorโ okay so this one emits extra code to check for buffer overflows, like stack smashing attacks ๐ก๏ธ It works by adding a guard variable to functions with vulnerable objects. That includes functions that callalloca, plus functions with buffers larger than or equal to 8 bytes. The guards get initialized when a function is entered and checked when it exits. If a guard check fails, an error message is printed and the program exits. Only variables that are actually allocated on the stack count, so optimized-away variables or variables allocated in registers don't ๐-fstack-protector-allโ like-fstack-protector, except every single function gets protected ๐-fstack-protector-strongโ like-fstack-protectorbut with extra functions added to the protected squad ๐ These are the ones with local array definitions, or ones that reference local frame addresses. Same rule as before: only variables actually allocated on the stack count, and optimized-away variables or variables allocated in registers don't.-fstack-protector-explicitโ like-fstack-protector, but it only protects the functions that have thestack_protectattribute ๐-fstack-checkโ generates code to verify that you don't go beyond the boundary of the stack ๐งฑ You should turn this on if you're running in an environment with multiple threads. You only rarely need it in a single-threaded environment, though, since stack overflow is automatically detected on nearly all systems when there's only one stack.
Note that this switch doesn't actually do the checking itself ๐ The operating system or the language runtime has to do that. The switch just makes sure they see the stack being extended.
You can also add a string parameter:
noโ no checking at allgenericโ forces the use of old-style checkingspecificโ uses the best checking method, and is equivalent to bare-fstack-check
Old-style checking is a generic mechanism that needs no specific target support in the compiler, but it comes with these drawbacks:
- Modified allocation strategy for large objects: they're always allocated dynamically if their size exceeds a fixed threshold. Note this may change the semantics of some code.
- Fixed limit on the size of the static frame of functions: when it is topped by a particular function, stack checking is not reliable and a warning is issued by the compiler.
- Inefficiency: because of both the modified allocation strategy and the generic implementation, code performance is hampered ๐ข
Old-style stack checking is also the fallback method for specific if no target support has been added in the compiler.
-fstack-check= is designed for Ada's needs to detect infinite recursion and stack overflows. specific is an excellent choice when compiling Ada code. It's not generally sufficient to protect against stack-clash attacks, though. To protect against those, you want -fstack-clash-protection ๐
-fstack-clash-protectionโ generates code to prevent stack clash style attacks ๐ฅ With this on, the compiler only allocates one page of stack space at a time, and each page is accessed immediately after allocation. That means allocations can't jump over any stack guard page the operating system provides ๐ก๏ธ
Most targets don't fully support stack clash protection. On those targets, though, -fstack-clash-protection will protect dynamic stack allocations. It may also provide limited protection for static stack allocations if the target supports -fstack-check=specific.
NOTE: In Ubuntu 19.10 and later versions,-fstack-clash-protectionis enabled by default for C, C++, ObjC, ObjC++, unless-fno-stack-clash-protectionis found.
-fstack-limit-register=reg,-fstack-limit-symbol=sym,-fno-stack-limitโ these make sure the stack doesn't grow beyond a certain value, either the value of a register or the address of a symbol ๐ง If a larger stack is needed, a signal is raised at run time. For most targets, the signal is raised before the stack overruns the boundary, so you can catch it without taking special precautions.
For instance, if the stack starts at absolute address 0x80000000 and grows downwards, you can use the flags -fstack-limit-symbol=__stack_limit and -Wl,--defsym,__stack_limit=0x7ffe0000 to enforce a stack limit of 128KB. Note that this may only work with the GNU linker.
You can locally override stack limit checking by using the no_stack_limit function attribute ๐
-fsplit-stackโ generates code to automatically split the stack before it overflows โ๏ธ The resulting program has a discontiguous stack, which can only overflow if the program is unable to allocate any more memory. This is most useful when running threaded programs, since you no longer need to calculate a good stack size to use for each thread. Right now it's only implemented for the x86 targets running GNU/Linux.
When code compiled with -fsplit-stack calls code compiled without it, there may not be much stack space left for the latter code to run. If compiling all code, including library code, with -fsplit-stack isn't an option, the linker can fix up these calls so that the code compiled without -fsplit-stack always gets a large stack. Support for this is implemented in the gold linker in GNU binutils release 2.21 and later ๐
-fvtable-verify=[std|preinit|none]โ this is only available when compiling C++ code ๐ฆ It turns on the security feature that verifies at run time, for every virtual call, that the vtable pointer used for the call is valid for the type of the object and hasn't been corrupted or overwritten. Using-fvtable-verify=noneturns it off instead. If an invalid vtable pointer is detected at run time, an error is reported and program execution is immediately halted ๐จ
This option causes run-time data structures to be built at program startup, and those are what get used to verify the vtable pointers. The std and preinit values control the timing of when these data structures get built. In both cases they're built before execution reaches main. With -fvtable-verify=std, they're built after shared libraries have been loaded and initialized. With -fvtable-verify=preinit, they're built before shared libraries have been loaded and initialized.
If this option appears multiple times on the command line with different values, none takes the highest priority over both std and preinit, and preinit takes priority over std ๐
-fvtv-debugโ used together with-fvtable-verify=stdor-fvtable-verify=preinit, this makes the compiler call debug versions of the runtime functions for the vtable verification feature ๐ It also makes the compiler log info about which vtable pointers it finds for each class. That info gets written to a file namedvtv_set_ptr_data.login the directory named by the environment variableVTV_LOGS_DIRif that's defined, or the current working directory otherwise.
Note: This feature appends data to the log file. If you want a fresh log file, be sure to delete any existing one ๐๏ธ
-fvtv-countsโ a debugging flag ๐งฎ When used together with-fvtable-verify=stdor-fvtable-verify=preinit, the compiler keeps track of the total number of virtual calls it encounters and the number of verifications it inserts. It also counts the calls to certain run-time library functions that it inserts, and logs this info for each compilation unit. The compiler writes this to a file namedvtv_count_data.login the directory named byVTV_LOGS_DIRif that's defined, or the current working directory otherwise. It also counts the size of the vtable pointer sets for each class, and writes that info tovtv_class_set_sizes.login the same directory.
Note: This feature appends data to the log files. To get fresh log files, be sure to delete any existing ones ๐งน
-finstrument-functionsโ generates instrumentation calls for entry and exit to functions ๐ญ Just after function entry and just before function exit, the following profiling functions are called with the address of the current function and its call site. On some platforms,__builtin_return_addressdoesn't work beyond the current function, so the call site information may not be available to the profiling functions otherwise.
void __cyg_profile_func_enter (void *this_fn,
void *call_site);
void __cyg_profile_func_exit (void *this_fn,
void *call_site);
The first argument is the address of the start of the current function, which can be looked up exactly in the symbol table ๐บ๏ธ
This instrumentation is also done for functions expanded inline in other functions. The profiling calls indicate where, conceptually, the inline function is entered and exited. This means that addressable versions of such functions must be available. If all your uses of a function are expanded inline, this may mean an additional expansion of code size. If you use extern inline in your C code, an addressable version of such functions must be provided. (This is normally the case anyway, but if you get lucky and the optimizer always expands the functions inline, you might have gotten away without providing static copies ๐)
A function can get the no_instrument_function attribute ๐ฆ, which tells GCC to skip instrumenting it. This is perfect for the profiling functions listed above, high-priority interrupt routines, and any function that can't safely call the profiling functions (think signal handlers, especially if the profiling routines generate output or allocate memory ๐).
-finstrument-functions-exclude-file-list=file,file,...โ Okay, this one is a whole vibe ๐ . It sets the list of files whose functions get left out of instrumentation (see-finstrument-functions). If the file holding a function definition matches any of the file entries, that function is skipped. The matching is by substring, so if your file value is a substring of the file name, it counts as a match ๐ซถ
For example:
-finstrument-functions-exclude-file-list=/bits/stl,include/sys
This excludes any inline function defined in files whose pathnames contain /bits/stl or include/sys โจ
If, for some reason, you need an actual comma inside one of your sym values, you type two commas, ,,. For example, -finstrument-functions-exclude-file-list=',,tmp' (note the single quotes around the whole option, bestie ๐).
-finstrument-functions-exclude-function-list=sym,sym,...โ This is basically the same energy as the file list, except it excludes by function name instead ๐ธ. The name it matches is the user-visible one, likevector<int> blah(const vector<int> &), not the internal mangled name like_Z4blahRSt6vectorIiSaIiEE๐. Matching is also by substring: if your sym is a substring of the function name, it's a match. For C99 and C++ extended identifiers, you have to write the function name in UTF-8, not with universal character names ๐-fpatchable-function-entry=N[,M]โ Okay, this one is giving "future-proof ๐ง". It generates N NOPs right at the start of each function, with the function entry point sitting before the Mth NOP. If you leave M out, it defaults to 0, so the entry point is the address right at the first NOP. Those NOPs reserve extra space that you can use to patch in instrumentation at run time, but only if the code segment is writable ๐ฅ. You control the size of that space indirectly through the number of NOPs. The NOP instruction used matches what the internal GCC back-end interfacegen_nopemits. This behavior is target-specific and may also depend on the architecture variant and/or other compilation options, so it's not one-size-fits-all ๐
For run-time identification, the starting addresses of these areas (which match each function entry minus M) also get collected in the __patchable_function_entries section of the final binary ๐
Heads up: the value of __attribute__ ((patchable_function_entry (N,M))) takes precedence over the command-line option -fpatchable-function-entry=N,M. That means you can use it to bump the area size up or remove it entirely on one specific function ๐
. If N=0, no pad location gets recorded.
The NOP instructions go in at the function entry address (and maybe before it, depending on M), and that happens even before the prologue ๐ฆ
โจ Options Controlling the Preprocessor โจ
Okay, these options control the C preprocessor, which runs on every C source file before the actual compilation happens ๐
If you use -E, nothing gets done except preprocessing. Some of these options only make sense together with -E, because they make the preprocessor output unsuitable for actual compilation ๐
Also, there are a bunch of options for controlling the search paths for include files, which you can find in Directory Options ๐บ๏ธ. Options for controlling preprocessor diagnostics are listed in Warning Options ๐ฅ.
-D nameโ Predefines name as a macro with the definition1๐-D name=definitionโ The contents of definition get tokenized and processed as if they showed up during translation phase three in a#definedirective. Heads up: the definition gets chopped off at any embedded newline characters โ๏ธ
If you're invoking the preprocessor from a shell (or something shell-like), you might need the shell's quoting syntax to protect characters like spaces that have a meaning in shell syntax ๐ซถ
Wanna define a function-like macro on the command line? Write its argument list in parentheses before the equals sign (if there is one). Parentheses mean something to most shells, so you should quote the option. With sh and csh, -D'name(args...)=definition' works ๐
-D and -U options are processed in the order you give them on the command line. All -imacros file and -include file options get processed after every -D and -U ๐ฆ
-U nameโ Cancels any previous definition of name, whether it was built in or provided with a-Doption ๐ง-include fileโ Processes file as if#include "file"appeared as the first line of the primary source file. The difference is that the first directory searched for file is the preprocessor's working directory, not the directory containing the main source file. If it isn't found there, it's searched for in the rest of the#include "..."search chain like normal ๐ธ
If you give multiple -include options, the files get included in the order they appear on the command line โจ
-imacros fileโ Exactly like-include, except any output produced by scanning file gets thrown away. The macros it defines stay defined ๐. This lets you grab all the macros from a header without also processing its declarations ๐
All files specified by -imacros get processed before all files specified by -include ๐
-undefโ Don't predefine any system-specific or GCC-specific macros. The standard predefined macros stay defined ๐-pthreadโ Defines the additional macros needed for using the POSIX threads library. Use this option consistently for both compilation and linking, bestie ๐ซถ. It's supported on GNU/Linux targets, most other Unix derivatives, and also on x86 Cygwin and MinGW targets โญ-Mโ Instead of outputting the preprocessed result, this outputs a rule suitable formakethat describes the dependencies of the main source file ๐. The preprocessor outputs one make rule containing the object file name for that source file, a colon, and the names of all the included files. That includes any coming from-includeor-imacroscommand-line options ๐ง
Unless you set it explicitly (with -MT or -MQ), the object file name is the source file's name with any suffix swapped for the object file suffix, and with any leading directory parts removed. If there are a lot of included files, the rule gets split across several lines using \-newline. The rule has no commands ๐
This option does not suppress the preprocessor's debug output, like -dM. To avoid mixing that debug output with your dependency rules, specify the dependency output file explicitly with -MF, or use an environment variable like DEPENDENCIES_OUTPUT. The debug output still goes to the regular output stream as usual ๐
Passing -M to the driver implies -E, and it suppresses warnings with an implicit -w ๐ฅ
-MMโ Like-M, but it doesn't mention header files found in system header directories, or header files that get included, directly or indirectly, from one of those system headers ๐ฆ
This also means the choice of angle brackets or double quotes in an #include directive doesn't, by itself, decide whether that header shows up in -MM dependency output ๐
-MF fileโ When used with-Mor-MM, this specifies a file to write the dependencies to. If you don't give a-MFswitch, the preprocessor sends the rules to the same place it would send preprocessed output ๐ธ
When you use it with the driver options -MD or -MMD, -MF overrides the default dependency output file ๐ซถ
If file is -, the dependencies get written to stdout โจ
-MGโ Used together with an option like-Mthat requests dependency generation,-MGassumes missing header files are generated files. It adds them to the dependency list without raising an error ๐ง. The dependency filename is taken straight from the#includedirective, without prepending any path ๐.-MGalso suppresses preprocessed output, since a missing header makes that useless ๐
This feature is used for automatically updating makefiles ๐
-MPโ This instructs CPP to add a phony target for each dependency other than the main file, so that each one depends on nothing ๐. These dummy rules work around the errorsmakethrows if you delete header files without updating the Makefile to match ๐ฅ
This is typical output:
test.o: test.c test.h
test.h:
-MT targetโ Changes the target of the rule emitted by dependency generation ๐. By default, CPP takes the name of the main input file, deletes any directory components and any file suffix like.c, and appends the platform's usual object suffix. That result is the target ๐ฆ
An -MT option sets the target to be exactly the string you specify. If you want multiple targets, you can put them all in a single argument to -MT, or use multiple -MT options ๐
For example, -MT '$(objpfx)foo.o' might give:
$(objpfx)foo.o: foo.c
-MQ targetโ Same as-MT, except it quotes any characters that are special to Make ๐ .-MQ '$(objpfx)foo.o'gives:
$$(objpfx)foo.o: foo.c
The default target gets automatically quoted, as if it had been given with -MQ โจ
-MDโ-MDis equivalent to-M -MF file, except that-Eis not implied ๐ซถ. The driver figures out file based on whether an-ooption is given. If it is, the driver uses that argument but with a.dsuffix. Otherwise, it takes the input file's name, removes any directory components and suffix, and applies a.dsuffix ๐ธ
If you use -MD together with -E, any -o switch is understood to specify the dependency output file. But if you use it without -E, each -o is understood to specify a target object file ๐
Since -E isn't implied, -MD can generate a dependency output file as a side effect of the compilation process ๐ง
-MMDโ Like-MD, except it only mentions user header files, not system header files ๐-fpreprocessedโ ๐ okay so this one tells the preprocessor "hey, this file is already preprocessed, don't redo it!" It skips macro expansion, trigraph conversion, escaped newline splicing, and most directives. Comments still get recognized and removed, so you can pass it a file preprocessed with-Cand it's totally fine ๐ซถ. In this mode the integrated preprocessor is basically just a tokenizer for the front ends ๐ง. And it's switched on automatically if the input file ends in.i,.ii, or.mi, which are the extensions GCC uses for preprocessed files made by-save-tempsโจ.-fdirectives-onlyโ ๐ฆ handle the directives but don't expand macros. What happens depends on-Eand-fpreprocessed:- With
-E, it only handles directives like#define,#ifdef, and#error. Stuff like macro expansion and trigraph conversion doesn't happen. Also,-dDgets turned on implicitly ๐ . - With
-fpreprocessed, predefining the command line and most builtin macros is disabled. Context-dependent macros like__LINE__are handled normally. This lets you compile files that were preprocessed with-E -fdirectives-only๐ธ. - With both
-Eand-fpreprocessed, the-fpreprocessedrules win. This gives you full preprocessing of files that were previously preprocessed with-E -fdirectives-only๐.
- With
-fdollars-in-identifiersโ ๐ lets$show up inside identifiers.-fextended-identifiersโ ๐ accepts universal character names and extended characters in identifiers. It's on by default for C99 (and later C standards) and C++, so you're already set ๐ญ.-fno-canonical-system-headersโ ๐ when preprocessing, this stops system header paths from being shortened with canonicalization.-fmax-include-depth=depthโ ๐ง sets the max depth of nested#includes. The default is200โจ.-ftabstop=widthโ ๐ sets the distance between tab stops. This helps the preprocessor report correct column numbers in warnings or errors, even when tabs are on the line ๐. If the value is less than1or greater than100, the option gets ignored. The default is8.-ftrack-macro-expansion[=level]โ ๐ tracks token locations across macro expansions. This lets the compiler print diagnostics about the current macro expansion stack when an error happens inside a macro. Heads up, though: it makes the preprocessor and compiler eat more memory ๐. The level picks how precisely tokens get tracked, so you can dial down memory use if you need to:0turns this option off.1tracks token locations in a degraded mode to keep memory overhead minimal. In this mode, every token from expanding a function-like macro's argument shares the same location.2tracks token locations completely. This is the most memory-hungry one ๐ฅ.
If you give the option with no argument, the level defaults to 2. Also, -ftrack-macro-expansion=2 is on by default, so it's already doing its thing ๐.
-fmacro-prefix-map=old=newโ ๐บ๏ธ when preprocessing files in directory old,__FILE__and__BASE_FILE__expand as if the files lived in directory new instead. You can use.for new to turn an absolute path into a relative one, which can make builds more reproducible and location independent ๐ฟ. This also affects__builtin_FILE()during compilation. See also-ffile-prefix-map.-fexec-charset=charsetโ ๐ sets the execution character set for string and character constants. The default isUTF-8. charset can be any encoding the system'siconvlibrary routine supports โจ.-fwide-exec-charset=charsetโ ๐ธ sets the wide execution character set for wide string and character constants. The default is one ofUTF-32BE,UTF-32LE,UTF-16BE, orUTF-16LE, whichever matches the width ofwchar_tand the big-endian or little-endian byte order used for code generation. Like-fexec-charset, charset can be any encodingiconvsupports, but you'll run into problems with encodings that don't fit exactly inwchar_t๐ฌ.-finput-charset=charsetโ ๐ฆ sets the input character set, which gets translated from the input file's character set into the source character set GCC uses. If the locale doesn't specify one, or GCC can't get it from the locale, the default isUTF-8. The locale or this command-line option can override it, but if they conflict, the command-line option wins ๐. charset can be any encoding the system'siconvlibrary routine supports.-fpch-depsโ ๐ง when you're using precompiled headers, this makes the dependency-output flags also list the files from the precompiled header's dependencies. Without it, only the precompiled header gets listed, not the files used to create it, since those aren't consulted when a precompiled header is used ๐.-fpch-preprocessโ ๐ lets you use a precompiled header together with-E. It inserts a special#pragmainto the output,#pragma GCC pch_preprocess "filename", to mark where the precompiled header was found and what its filename is. When-fpreprocessedis in use, GCC recognizes this#pragmaand loads the PCH ๐ซถ.
This option is off by default, since the preprocessed output is really only suitable as input to GCC. It gets switched on by -save-temps ๐.
You shouldn't write this #pragma in your own code. But it's safe to edit the filename if the PCH file lives somewhere else. The filename can be absolute or relative to GCC's current directory ๐๏ธ.
-fworking-directoryโ ๐ turns on linemarkers in the preprocessor output that tell the compiler the working directory at preprocessing time. With this on, after the initial linemarker, the preprocessor emits a second linemarker with the current working directory followed by two slashes. GCC uses that directory, if it's in the preprocessed input, as the working directory in some debugging information formats โจ. It's implicitly enabled when debugging info is on, but you can turn it off with the negated form-fno-working-directory. If-Pis in the command line, this option does nothing, since no#linedirectives get emitted whatsoever ๐.-A predicate=answerโ ๐ฎ makes an assertion with the predicate predicate and the answer answer. This form is preferred over the older-A predicate(answer)form, which is still supported. The new one is better because it doesn't use shell special characters ๐ .-A -predicate=answerโ ๐ซ cancels an assertion with the predicate predicate and the answer answer.-Cโ ๐ฌ don't throw away comments! All comments get passed through to the output file, except comments in processed directives, which get deleted along with the directive.
โ ๏ธ Be ready for side effects when you use-C. It makes the preprocessor treat comments as tokens in their own right. For example, a comment at the start of what would be a directive line turns that line into an ordinary source line, since the first token on the line is no longer a#๐.
-CCโ ๐ don't throw away comments, including during macro expansion. It's like-C, except comments inside macros also get passed through to the output file wherever the macro is expanded.
In addition to the -C side effects, -CC converts all C++-style comments inside a macro into C-style comments. This stops later uses of that macro from accidentally commenting out the rest of the source line ๐
โโ๏ธ. -CC is mostly used to support lint comments ๐งน.
-Pโ ๐ซ inhibits linemarkers in the preprocessor output. This could be useful when you run the preprocessor on something that isn't C code and will get sent to a program that might get confused by linemarkers ๐ธ.-traditional,-traditional-cppโ ๐ฐ๏ธ try to imitate pre-standard C preprocessors instead of ISO C preprocessors. Check the GNU CPP manual for the details ๐.
Also, GCC doesn't try to emulate a pre-standard C compiler otherwise, and these options only work with the -E switch or when you invoke CPP explicitly ๐.
-trigraphsโ ๐ค supports ISO C trigraphs. These are three-character sequences that all start with??and that ISO C defines as stand-ins for single characters. For example,??/stands for\, so'??/n'is a character constant for a newline ๐.
The nine trigraphs and their replacements are:
Trigraph: ??( ??) ??< ??> ??= ??/ ??' ??! ??-
Replacement: [ ] { } # \ ^ | ~
By default GCC ignores trigraphs, but in standard-conforming modes it converts them. Check out the -std and -ansi options for that ๐.
-remapโ ๐๏ธ enables special code to work around file systems that only allow very short file names, like MS-DOS ๐พ.-Hโ ๐ณ prints the name of each header file used, along with all the other normal stuff. Each name is indented to show how deep it is in the#includestack ๐ช. Precompiled header files get printed too, even if they turn out to be invalid. An invalid one gets printed with...x, and a valid one with...!โจ.-dlettersโ ๐ฅ makes debugging dumps during compilation, as specified by letters. The flags documented here are the ones relevant to the preprocessor. Other letters get interpreted by the compiler proper, or are reserved for future GCC versions, so they're silently ignored ๐ซฅ.
โ ๏ธ If you specify letters whose behavior conflicts, the result is undefined. Yikes ๐ญ.
-dMโ ๐ instead of the normal output, this generates a list of#definedirectives for all the macros defined during the preprocessor's execution, including predefined macros. It's a great way to find out what's predefined in your version of the preprocessor ๐ซถ. Assuming you have no file foo.h, the command
Okay bestie, just run this and watch the magic โจ
touch foo.h; cpp -dM foo.h
And boom, it shows you all the predefined macros ๐ Every single one, no cap.
๐ If you use-dMwithout the-Eoption,-dMgets treated as a synonym for-fdump-rtl-mach. Not me being dramatic, that's just how it works.
-dDโ ๐ This one's like-dM, but different in two ways. It skips the predefined macros, and it outputs both the#definedirectives and the result of preprocessing. Both kinds of output go to the standard output file ๐ฆ-dNโ Same energy as-dD, but it only gives you the macro names and skips their expansions ๐ธ-dIโ Adds#includedirectives to the output, on top of the result of preprocessing ๐ง-dUโ Like-dD, but way pickier ๐ Only macros that get expanded, or whose definedness gets tested in preprocessor directives, make it into the output. The output is delayed until the macro is used or tested, and#undefdirectives also show up for macros that were tested but undefined at that moment.-fdebug-cppโ This one's only useful if you're debugging GCC itself, bestie ๐ง When it's used from CPP or with-E, it dumps debugging info about location maps. Every token in the output gets preceded by the dump of the map its location belongs to.
When it's used from GCC without -E, this option has no effect ๐ซ
-Wp,optionโ You can use this to skip the compiler driver and passoptionstraight through to the preprocessor ๐ Ifoptionhas commas in it, it gets split into multiple options at those commas. Heads up though, because a lot of options get modified, translated, or interpreted by the compiler driver before they reach the preprocessor, and-Wpforcibly skips that step.
๐จ The preprocessor's direct interface is undocumented and subject to change, so whenever possible, avoid -Wp and let the driver handle the options instead ๐ฅบ
-Xpreprocessor optionโ Passesoptionto the preprocessor ๐ Use this for system-specific preprocessor options that GCC doesn't recognize. If the option you want takes an argument, you have to use-Xpreprocessortwice: once for the option and once for the argument.-no-integrated-cppโ By default, GCC does preprocessing as an integrated part of input tokenization and parsing, all smooth and built in ๐ With this option, preprocessing happens as a separate pass before compilation instead. The appropriate language front end (cc1,cc1plus, orcc1objfor C, C++, and Objective-C, respectively) gets invoked twice: once for preprocessing only, and once for the actual compilation of the preprocessed input. This can be handy with-Bor-wrapperif you want an alternate preprocessor, or extra processing of your source between normal preprocessing and compilation ๐
โจ Passing Options to the Assembler โจ
You can pass options to the assembler ๐ฆ
-Wa,optionโ Passesoptionto the assembler. Ifoptioncontains commas, it gets split into multiple options at the commas.-Xassembler optionโ Passesoptionto the assembler ๐ ๏ธ Use this for system-specific assembler options that GCC doesn't recognize. If the option takes an argument, you have to use-Xassemblertwice: once for the option and once for the argument.
โจ Options for Linking โจ
These options come into play when the compiler links object files into an executable output file ๐ They're meaningless if the compiler isn't doing a link step, so don't bother with them then.
object-file-nameโ A file name that doesn't end in a special recognized suffix is considered to name an object file or library. (The linker tells object files and libraries apart by looking at the file contents.) If linking is done, these object files get used as input to the linker.-c,-S,-Eโ If any of these options is used, the linker doesn't run, so object file names should not be used as arguments ๐-flinker-output=typeโ This option controls code generation for the link-time optimizer ๐ง By default, the linker output is automatically determined by the linker plugin. For debugging the compiler, or if you want incremental linking with a non-LTO object file, it can be useful to set the type manually. Here's the lowdown on each type:execโ Code generation produces a static binary. In this case-fpicand-fpieare both disabled.dynโ Code generation produces a shared library. In this case-fpicor-fPICis preserved, but not enabled automatically. This lets you build shared libraries without position-independent code on architectures where that's possible, i.e. on x86.pieโ Code generation produces an-fpieexecutable. This results in similar optimizations asexec, except-fpieis not disabled if it was specified at compilation time.relโ The compiler assumes incremental linking is happening. The sections containing intermediate code for link-time optimization get merged, pre-optimized, and output to the resulting object file. If-ffat-lto-objectsis specified, binary code is also produced for future non-LTO linking. The object file produced by incremental linking is smaller than a static library made from the same object files. At link time, the result also loads faster than a static library, assuming that most objects in the library are used.nolto-relโ Configures the compiler for incremental linking where code generation is forced, a final binary is produced, and the intermediate code for later link-time optimization is stripped. When multiple object files are linked together, the result is better optimized than with link-time optimizations disabled (cross-module inlining happens, for example), but most of the benefits of whole program optimizations are lost.
During the incremental link (by -r), the linker plugin defaults to rel. With current interfaces to GNU Binutils, it's not possible to incrementally link LTO objects and non-LTO objects into a single mixed object file ๐ญ If any object file in an incremental link can't be used for link-time optimization, the linker plugin issues a warning and uses nolto-rel. To maintain whole program optimization, it's recommended to link such objects into a static library instead. Alternatively, it's possible to use H.J. Lu's binutils, which have support for mixed objects ๐
-fuse-ld=bfdโ Uses the bfd linker instead of the default linker ๐-fuse-ld=goldโ Uses the gold linker instead of the default linker โจ-fuse-ld=lldโ Uses the LLVM lld linker instead of the default linker ๐-fuse-ld=moldโ Uses the Modern Linker (mold) instead of the default linker ๐ฅ-llibrary,-l libraryโ Searches the library namedlibrarywhen linking ๐ The second form, with the library as a separate argument, is only there for POSIX compliance and isn't recommended ๐
The -l option is passed directly to the linker by GCC, so check your linker's documentation for the exact details ๐ The general description below applies to the GNU linker.
The linker searches a standard list of directories for the library. Those directories include several standard system directories, plus any you specify with -L ๐บ๏ธ
Static libraries are archives of object files, and they have file names like liblibrary.a. Some targets also support shared libraries, which typically have names like liblibrary.so. If both static and shared libraries are found, the linker gives preference to linking with the shared library unless the -static option is used ๐
Where you write this option in the command really matters ๐ The linker searches and processes libraries and object files in the order they're specified. So foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not get loaded ๐ฌ
-lobjcโ You need this special case of the-loption to link an Objective-C or Objective-C++ program ๐ง-nostartfilesโ Don't use the standard system startup files when linking ๐ซ The standard system libraries are still used normally, unless-nostdlib,-nolibc, or-nodefaultlibsis used.-nodefaultlibsโ Don't use the standard system libraries when linking. Only the libraries you specify are passed to the linker, and options specifying linkage of the system libraries, such as-static-libgccor-shared-libgcc, are ignored. The standard startup files are used normally, unless-nostartfilesis used.
The compiler may generate calls to "memcmp", "memset", "memcpy" and "memmove". These entries are usually resolved by entries in libc. When this option is specified, these entry points should be supplied through some other mechanism ๐ซถ
-nolibcโ Don't use the C library, or the system libraries tightly coupled with it, when linking. It still links with the startup files, libgcc, or toolchain-provided language support libraries such aslibgnat,libgfortran, orlibstdc++, unless options preventing their inclusion are used as well. This typically removes-lcfrom the link command line, along with the system libraries that normally go with it and become meaningless when a C library is assumed absent, for example-lpthreador-lmin some configurations. This is intended for bare-board targets where there is indeed no C library available ๐ค-nostdlibโ Don't use the standard system startup files or libraries when linking. No startup files are used, and only the libraries you specify are passed to the linker. Options specifying linkage of the system libraries, such as-static-libgccor-shared-libgcc, are ignored.
The compiler may generate calls to "memcmp", "memset", "memcpy" and "memmove". These entries are usually resolved by entries in libc. When this option is specified, these entry points should be supplied through some other mechanism ๐
One of the standard libraries bypassed by -nostdlib and -nodefaultlibs is libgcc.a, a library of internal subroutines which GCC uses to overcome shortcomings of particular machines, or special needs for some languages ๐ธ
You almost always still need libgcc.a ๐ญ, even when you're trying to ditch the other standard libraries ๐. So if you go with -nostdlib or -nodefaultlibs, you should usually throw -lgcc in there too ๐ซถ. That way you won't end up with unresolved references to GCC's internal library subroutines ๐
. (__main is one of those internal helpers, and it's what makes sure C++ constructors get called โจ.)
-e entry,--entry=entryโ Sets the program's entry point toentry๐ง. The linker is the one reading this, and the GNU linker will happily take either a symbol name or an address.-pieโ Makes a dynamically linked position independent executable on targets that support it ๐ฆ. For predictable results, you also need to use the same options you compiled with (-fpie,-fPIE, or model suboptions) when you pass this linker option.-no-pieโ Nope, no PIE for you. This makes a dynamically linked position independent executable not happen ๐ โโ๏ธ.-static-pieโ Makes a static position independent executable on targets that support it ๐. It's basically a static executable, except it can be loaded at any address without needing a dynamic linker. Same deal as before: for predictable results, match your compile options (-fpie,-fPIE, or model suboptions) when you use this linker option.-pthreadโ Links with the POSIX threads library ๐งต. This works on GNU/Linux targets, most other Unix derivatives, and also on x86 Cygwin and MinGW targets. On some targets it also sets flags for the preprocessor, so use it consistently for both compiling and linking or it'll get messy ๐.-rโ Produces a relocatable object as output. This is also known as partial linking ๐ธ.-rdynamicโ Passes the flag-export-dynamicto the ELF linker, on targets that support it ๐. This tells the linker to add all symbols to the dynamic symbol table, not only the ones that are used. It's needed for some uses ofdlopenor to get backtraces from inside a program ๐ฅ.-sโ Strips out all symbol table and relocation information from the executable ๐ช.-staticโ On systems that support dynamic linking, this overrides-pieand stops linking with shared libraries ๐ซ. On other systems it does absolutely nothing ๐คทโโ๏ธ.-sharedโ Makes a shared object that you can link with other objects to form an executable. Not every system supports this one ๐ฅบ. For predictable results, match your compile options (-fpic,-fPIC, or model suboptions) when you use this linker option.[1]-shared-libgcc,-static-libgccโ On systems that ship libgcc as a shared library, these force the shared or static version, respectively ๐. If no shared version of libgcc was built when the compiler was configured, these do nothing at all.
There are a few situations where an app should use the shared libgcc instead of the static one ๐. The biggest one is when the app wants to throw and catch exceptions across different shared libraries. In that case, every one of those libraries and the app itself should use the shared libgcc ๐ซถ.
So the G++ driver automatically adds -shared-libgcc whenever you build a shared library or a main executable. C++ programs use exceptions all the time, so this is the right move ๐
.
If you use the GCC driver to make shared libraries instead, they might not always end up linked with the shared libgcc ๐. If GCC finds out at configuration time that you have a non-GNU linker, or a GNU linker that doesn't support the option --eh-frame-hdr, it links the shared version of libgcc into shared libraries by default. Otherwise, it takes advantage of the linker and skips linking with the shared libgcc, using the static version by default instead. This lets exceptions propagate through those shared libraries without paying relocation costs at library load time โจ.
However, if a library or main executable is supposed to throw or catch exceptions, you must link it using the G++ driver, or use the option -shared-libgcc, so that it's linked with the shared libgcc. Don't skip this or your exceptions will be ghosting you ๐.
-static-libasanโ When-fsanitize=addressis used to link a program, the GCC driver automatically links against libasan ๐. If libasan is available as a shared library and-staticisn't used, it links against the shared version. This option tells the GCC driver to link libasan statically, without necessarily linking other libraries statically.-static-libtsanโ When-fsanitize=threadis used to link a program, the GCC driver automatically links against libtsan ๐งต. If libtsan is available as a shared library and-staticisn't used, it links against the shared version. This option tells the GCC driver to link libtsan statically, without necessarily linking other libraries statically.-static-liblsanโ When-fsanitize=leakis used to link a program, the GCC driver automatically links against liblsan ๐ต๏ธโโ๏ธ. If liblsan is available as a shared library and-staticisn't used, it links against the shared version. This option tells the GCC driver to link liblsan statically, without necessarily linking other libraries statically.-static-libubsanโ When-fsanitize=undefinedis used to link a program, the GCC driver automatically links against libubsan ๐ซ . If libubsan is available as a shared library and-staticisn't used, it links against the shared version. This option tells the GCC driver to link libubsan statically, without necessarily linking other libraries statically.-static-libstdc++โ When theg++program links a C++ program, it normally links against libstdc++ automatically ๐. If libstdc++ is available as a shared library and-staticisn't used, it links against the shared version, and that's usually totally fine ๐. Sometimes, though, you want to freeze the libstdc++ version your program uses without going all the way to a fully static link. This option tells theg++driver to link libstdc++ statically, without necessarily linking other libraries statically.-symbolicโ Binds references to global symbols when building a shared object ๐. It warns about any unresolved references (unless you override that with the link editor option-Xlinker -z -Xlinker defs). Only a few systems support this one, so it's a bit of a rare bird ๐ฆ.-T scriptโ Usesscriptas the linker script ๐. This works on most systems that use the GNU linker. On some targets, like bare-board targets with no operating system,-Tmay be required when linking so you don't get references to undefined symbols ๐ฌ.-Xlinker optionโ Passesoptionalong to the linker as an option ๐. This is your escape hatch for system-specific linker options that GCC doesn't recognize.
If you want to pass an option that takes a separate argument, you have to use -Xlinker twice: once for the option and once for the argument. For example, to pass -assert definitions, you write -Xlinker -assert -Xlinker definitions. Writing -Xlinker "-assert definitions" does not work, because it passes the whole string as one single argument, and that's not what the linker expects ๐
โโ๏ธ.
When you're using the GNU linker, it's usually way more convenient to pass arguments with the option=value syntax instead of as separate arguments. For example, -Xlinker -Map=output.map is much nicer than -Xlinker -Map -Xlinker output.map. Other linkers might not support this syntax for command-line options, though ๐ค.
-Wl,optionโ Passesoptionto the linker as an option ๐ง. Ifoptionhas commas in it, it gets split into multiple options at each comma. This is how you pass an argument to an option:-Wl,-Map,output.mappasses-Map output.mapto the linker. With the GNU linker, you can also get the same effect with-Wl,-Map=output.map๐ .
NOTE: In Ubuntu 8.10 and later versions, for LDFLAGS, the option-Wl,-z,relrois used. To turn that off, use-Wl,-z,norelro๐.
-u symbolโ Pretends the symbolsymbolis undefined, which forces the linker to load library modules that define it ๐ญ. You can use-umultiple times with different symbols to force loading of extra library modules.-z keywordโ Passes-zdirectly to the linker along with thekeyword๐ฏ. Check the documentation for your linker to see the permitted values and what they mean.
โจ Options for Directory Search โจ
These options are how you tell GCC which directories to search for header files, libraries, and parts of the compiler ๐๏ธ:
-I dirโ Adds the directorydirto the list of directories searched for header files during preprocessing ๐. Ifdirbegins with=or$SYSROOT, that=or$SYSROOTgets replaced by the sysroot prefix (see--sysrootand-isysroot).-iquote dirโ Addsdirfor the quote form only, which is#include "file"๐ฌ.-isystem dirโ Addsdirto the search list for both#include "file"and#include <file>๐ฐ.-idirafter dirโ Addsdirto the search list for both#include "file"and#include <file>, but it gets searched last ๐.
Quick note on those -iquote, -I, -isystem, and -idirafter lines: -iquote only applies to the quote form, while -I, -isystem, and -idirafter apply to both forms ๐. Also, you can mix and match any number or combination of these on the command line to search several directories ๐. Here's the lookup order, bestie ๐:
- For the quote form of the include directive, the directory of the current file is searched first ๐.
- For the quote form of the include directive, the directories given by
-iquoteoptions are searched left to right, in the order they appear on the command line โก๏ธ. - Directories given with
-Ioptions are scanned left to right ๐. - Directories given with
-isystemoptions are scanned left to right ๐ซง. - Standard system directories are scanned ๐๏ธ.
- Directories given with
-idirafteroptions are scanned left to right, last of all ๐ฆ.
You can use -I to override a system header file by swapping in your own version, since these directories get searched before the standard system header directories. ngl, though, don't use this to add directories full of vendor-supplied system headers. Use -isystem for that ๐ซถ
-isystem and -idirafter also mark a directory as a system directory, so it gets the same special treatment as the standard system directories ๐
If a standard system include directory, or one you gave with -isystem, also shows up in an -I, the -I gets ignored ๐ The directory still gets searched, but as a system directory in its normal spot in the system include chain. This is so GCC's procedure for fixing buggy system headers and the ordering for the #include_next directive don't get messed up by accident. If you really need to change the search order for system directories, use -nostdinc and/or -isystem instead โจ
-I-โ Splits the include path. This one is deprecated, so please switch to-iquotefor any-Idirectories that come before the-I-, and then remove the-I-entirely ๐
Any directories given with -I before the -I- only get searched for headers requested with #include "file". They're not searched for #include <file>. If you add more -I directories after the -I-, those get searched for every #include directive ๐ง
On top of that, -I- stops the directory of the current file from being used as the first search directory for #include "file". There's no way to undo this effect of -I-, so choose wisely bestie ๐ญ
-iprefix prefixโ Sets prefix as the prefix for any-iwithprefixoptions that come after it. If the prefix is a directory, make sure you include the final/๐ธ-iwithprefix dir,-iwithprefixbefore dirโ Tacks dir onto the prefix you set earlier with-iprefix, then adds the resulting directory to the include search path.-iwithprefixbeforeputs it in the same spot-Iwould, while-iwithprefixputs it where-idirafterwould ๐ฆ-isysroot dirโ This is basically--sysroot, but it only applies to header files. The exception is Darwin targets, where it applies to both headers and libraries. Check out--sysrootfor the full scoop ๐-imultilib dirโ Uses dir as a subdirectory of the directory that holds the target-specific C++ headers ๐-nostdincโ Skips the standard system directories when hunting for header files. Only the directories you explicitly gave with-I,-iquote,-isystem, and/or-idirafterget searched, plus the directory of the current file if that's appropriate ๐-nostdinc++โ Skips the C++-specific standard directories, but still searches the other standard directories. This one is used when building the C++ library ๐-iplugindir=dirโ Sets the directory to search for plugins that get passed by-fplugin=nameinstead of-fplugin=path/name.so. This one isn't meant for you to use directly. Only the driver passes it along ๐-Ldirโ Adds dir to the list of directories searched for-lโจ-Bprefixโ Tells the compiler where to find its own executables, libraries, include files, and data files ๐ฅ
The compiler driver runs one or more of the subprograms cpp, cc1, as, and ld. It tries prefix as a prefix for each program it attempts to run, both with and without machine/version/ for the target machine and compiler version. It's giving organized ๐
For each subprogram, the driver tries the -B prefix first, if you gave one. If that name isn't found, or if -B wasn't specified at all, the driver tries two standard prefixes: /usr/lib/gcc/ and /usr/local/lib/gcc/. If neither of those gets it a file that exists, the unmodified program name gets searched for in the directories listed in your PATH environment variable ๐ง
The compiler checks whether the path you gave with -B is a directory, and if it needs to, it adds a directory separator character to the end of the path ๐
-B prefixes that effectively name directories also apply to libraries in the linker, because the compiler translates them into -L options for the linker. They also apply to include files in the preprocessor, since the compiler translates them into -isystem options for the preprocessor. In that case, the compiler appends include to the prefix ๐ฆ
The runtime support file libgcc.a can also be searched for using the -B prefix, if needed. If it isn't found there, the two standard prefixes above get tried, and that's it. If it still isn't found by any of those means, the file gets left out of the link ๐ญ
Another way to specify a prefix that's pretty much like the -B prefix is the environment variable GCC_EXEC_PREFIX ๐ธ
As a special kludge, if the path given with -B is [dir/]stageN/, where N is a number from 0 to 9, it gets replaced by [dir/]include. This is there to help with bootstrapping the compiler ๐ง
-no-canonical-prefixesโ Don't expand any symbolic links, resolve references to/../or/./, or make the path absolute when generating a relative prefix ๐--sysroot=dirโ Uses dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in/usr/includeand libraries in/usr/lib, it'll instead searchdir/usr/includeanddir/usr/lib๐
If you use both this option and -isysroot, then --sysroot applies to libraries, but -isysroot applies to header files ๐
The GNU linker (version 2.16 and up) has the support it needs for this option. If your linker doesn't support it, the header file part of --sysroot still works, but the library part doesn't ๐
--no-sysroot-suffixโ For some targets, a suffix gets tacked onto the root directory you specify with--sysroot, depending on the other options you used. That means headers might get found indir/suffix/usr/includeinstead ofdir/usr/include. This option turns off adding that suffix ๐
โจ Options for Code Generation Conventions โจ
These machine-independent options control the interface conventions used in code generation, and they're lowkey iconic ๐
Most of them have both positive and negative forms. The negative form of -ffoo is -fno-foo. In the table below, only one of the forms gets listed, the one that isn't the default. You can figure out the other form by either removing no- or adding it ๐ฆ
-fstack-reuse=reuse-levelโ Controls stack space reuse for user-declared local/auto variables and compiler-generated temporaries. reuse_level can beall,named_vars, ornone.allenables stack reuse for all local variables and temporaries,named_varsenables reuse only for user-defined local variables that have names, andnonedisables stack reuse completely. The default value isall. This option is needed when a program extends the lifetime of a scoped local variable or a compiler-generated temporary beyond the end point the language defines. When a variable's lifetime ends and it lives in memory, the optimizing compiler is free to reuse its stack space for other temporaries or scoped local variables whose live range doesn't overlap with it. Legacy code that extends local lifetimes is likely to break with the stack reuse optimization ๐ฅ
For example,
int *p;
{
int local1;
p = &local1;
local1 = 10;
....
}
{
int local2;
local2 = 20;
...
}
if (*p == 10) // out of scope use of local1
{
}
Another example:
struct A
{
A(int k) : i(k), j(k) { }
int i;
int j;
};
A *ap;
void foo(const A& ar)
{
ap = &ar;
}
void bar()
{
foo(A(10)); // temp object's lifetime ends when foo returns
{
A a(20);
....
}
ap->i+= 10; // ap references out of scope temp whose space
// is reused with a. What is the value of ap->i?
}
The lifetime of a compiler-generated temporary is well defined by the C++ standard. When a temporary's lifetime ends and it lives in memory, the optimizing compiler is free to reuse its stack space for other temporaries or scoped local variables whose live range doesn't overlap with it. However, some legacy code relies on the behavior of older compilers, where temporaries' stack space wasn't reused. Aggressive stack reuse can lead to runtime errors for that code ๐ญ This option controls the temporary stack reuse optimization ๐ซถ
-ftrapvโ Generates traps for signed overflow on addition, subtraction, and multiplication operations.-ftrapvand-fwrapvoverride each other, so-ftrapv -fwrapvon the command line results in-fwrapvbeing effective. Only active options override, though, so-ftrapv -fwrapv -fno-wrapvon the command line results in-ftrapvbeing effective ๐ง-fwrapvโ Tells the compiler to assume that signed arithmetic overflow of addition, subtraction, and multiplication wraps around using twos-complement representation. This flag enables some optimizations and disables others.-ftrapvand-fwrapvoverride each other, so-ftrapv -fwrapvon the command line results in-fwrapvbeing effective. Only active options override, so-ftrapv -fwrapv -fno-wrapvon the command line results in-ftrapvbeing effective ๐-fwrapv-pointerโ okay so this tells the compiler to assume pointer arithmetic overflow on addition and subtraction just wraps around, using twos-complement representation ๐. It also turns off some optimizations that assume pointer overflow is invalid, so it's a bit of a plot twist ๐-fstrict-overflowโ this one implies-fno-wrapv -fno-wrapv-pointer๐ . When you negate it, it implies-fwrapv -fwrapv-pointerinstead โจ-fexceptionsโ enables exception handling and generates the extra code needed to propagate exceptions ๐ฅ. On some targets this also means GCC generates frame unwind information for all functions. That can add a lot of data size overhead, but it doesn't change how things execute ๐ง
If you don't specify this option, GCC turns it on by default for languages like C++ that normally need exception handling, and turns it off for languages like C that don't ๐. Still, you might need to enable it when compiling C code that has to interoperate properly with exception handlers written in C++ ๐ซถ. You might also want to disable it if you're compiling older C++ programs that don't use exception handling ๐
-fnon-call-exceptionsโ makes trapping instructions able to throw exceptions ๐ช. Heads up: this needs platform-specific runtime support, which doesn't exist everywhere ๐ญ. It also only lets trapping instructions throw exceptions, meaning memory references or floating-point instructions. It can't throw exceptions out of arbitrary signal handlers like"SIGALRM"๐-fdelete-dead-exceptionsโ instructions that may throw exceptions but don't otherwise contribute to the program's execution can be optimized away ๐๏ธ. This is enabled by default for the Ada front end, which the Ada language specification allows. Optimization passes that remove dead exceptions are enabled independently at different optimization levels ๐-funwind-tablesโ similar to-fexceptions, except it only generates any needed static data and leaves the generated code alone otherwise ๐ฆ. You usually don't need to enable this yourself, because a language processor that needs this handling turns it on for you ๐ซถ-fasynchronous-unwind-tablesโ generates an unwind table in DWARF format, if the target machine supports it ๐. The table is exact at each instruction boundary, so it can be used for stack unwinding from asynchronous events, like a debugger or garbage collector ๐-fno-gnu-uniqueโ on systems with a recent GNU assembler and C library, the C++ compiler uses the"STB_GNU_UNIQUE"binding ๐งฉ. That keeps definitions of template static data members and static local variables in inline functions unique, even with"RTLD_LOCAL". It's needed to avoid problems with a library used by two different"RTLD_LOCAL"plugins that depend on a definition in one of them and disagree with the other about the binding of the symbol ๐คฏ
The catch is that this makes dlclose get ignored for affected DSOs ๐. So if your program relies on reinitializing a DSO via dlclose and dlopen, you can use -fno-gnu-unique ๐
-fpcc-struct-returnโ returnsshortstructandunionvalues in memory like the longer ones, instead of in registers ๐ฆ. It's less efficient, but it lets GCC-compiled files play nicely with files compiled by other compilers, especially the Portable C Compiler (pcc) ๐ค
The exact convention for returning structures in memory depends on the target configuration macros ๐ฏ. Short structures and unions are the ones whose size and alignment match some integer type ๐
Warning: code compiled with the-fpcc-struct-returnswitch is not binary compatible with code compiled with the-freg-struct-returnswitch ๐ฌ. Only use it to conform to a non-default application binary interface.
-freg-struct-returnโ returnsstructandunionvalues in registers when possible โก. This is more efficient for small structures than-fpcc-struct-return๐
If you specify neither -fpcc-struct-return nor -freg-struct-return, GCC defaults to whichever convention is standard for the target ๐. If there's no standard convention, GCC defaults to -fpcc-struct-return, except on targets where GCC is the principal compiler. In those cases we can choose the standard, and we chose the more efficient register return alternative ๐
Warning: code compiled with the-freg-struct-returnswitch is not binary compatible with code compiled with the-fpcc-struct-returnswitch ๐ฌ. Only use it to conform to a non-default application binary interface.
-fshort-enumsโ allocates to anenumtype only as many bytes as it needs for the declared range of possible values ๐ข. Specifically, theenumtype ends up equivalent to the smallest integer type that has enough room ๐งธ
Warning: the -fshort-enums switch causes GCC to generate code that is not binary compatible with code generated without that switch ๐ฌ. Only use it to conform to a non-default application binary interface.
-fshort-wcharโ overrides the underlying type forwchar_tto beshort unsigned intinstead of the target's default ๐. This one is useful for building programs that run under WINE ๐ท
Warning: the -fshort-wchar switch causes GCC to generate code that is not binary compatible with code generated without that switch ๐ฌ. Only use it to conform to a non-default application binary interface.
-fcommonโ in C code, this controls where global variables defined without an initializer get placed ๐๏ธ. The C standard calls these tentative definitions. They're different from declarations of a variable with theexternkeyword, which don't allocate any storage ๐ซง
The default is -fno-common, which means the compiler places uninitialized global variables in the BSS section of the object file ๐๏ธ. This stops the linker from merging tentative definitions, so you get a multiple-definition error if the same variable is accidentally defined in more than one compilation unit ๐จ
-fcommon places uninitialized global variables in a common block instead ๐งบ. That lets the linker resolve all tentative definitions of the same variable in different compilation units to the same object, or to a non-tentative definition. It's inconsistent with C++, and on many targets it implies a speed and code size penalty on global variable references ๐ข. It's mainly useful for letting legacy code link without errors ๐ฅน
-fno-identโ ignore the#identdirective ๐ โโ๏ธ-finhibit-size-directiveโ don't output a.sizeassembler directive, or anything else that would cause trouble if the function is split in the middle and the two halves end up placed far apart in memory โ๏ธ. This is used when compiling crtstuff.c ๐งฉ. You shouldn't need it for anything else ๐ โโ๏ธ-fverbose-asmโ puts extra commentary in the generated assembly code so it's easier to read ๐. This is mostly for people who actually need to read the generated assembly, like when debugging the compiler itself ๐ต๏ธโโ๏ธ
-fno-verbose-asm, the default, leaves the extra information out, which is handy when comparing two assembler files โ๏ธ
The added comments include:
- information on the compiler version and command-line options,
- the source code lines associated with the assembly instructions, in the form FILENAME:LINENUMBER:CONTENT OF LINE,
- hints on which high-level expressions correspond to the various assembly instruction operands.
For example, here's a C source file:
int test (int n)
{
int i;
int total = 0;
for (i = 0; i < n; i++)
total += i * i;
return total;
}
Compiling it to (x86_64) assembly via -S and sending the result straight to stdout via -o - looks like this:
gcc -S test.c -fverbose-asm -Os -o -
That gives output similar to this ๐:
.file "test.c"
# GNU C11 (GCC) version 7.0.0 20160809 (experimental) (x86_64-pc-linux-gnu)
[...snip...]
# options passed:
[...snip...]
.text
.globl test
.type test, @function
test:
.LFB0:
.cfi_startproc
# test.c:4: int total = 0;
xorl %eax, %eax # <retval>
# test.c:6: for (i = 0; i < n; i++)
xorl %edx, %edx # i
.L2:
# test.c:6: for (i = 0; i < n; i++)
cmpl %edi, %edx # n, i
jge .L5 #,
# test.c:7: total += i * i;
movl %edx, %ecx # i, tmp92
imull %edx, %ecx # i, tmp92
# test.c:6: for (i = 0; i < n; i++)
incl %edx # i
# test.c:7: total += i * i;
addl %ecx, %eax # tmp92, <retval>
jmp .L2 #
.L5:
# test.c:10: }
ret
.cfi_endproc
.LFE0:
.size test, .-test
.ident "GCC: (GNU) 7.0.0 20160809 (experimental)"
.section .note.GNU-stack,"",@progbits
The comments are meant for humans rather than machines, so the precise format of them is subject to change ๐ซถ
-frecord-gcc-switchesโ records the command line used to invoke the compiler into the object file being created ๐ผ. This is only implemented on some targets, and the exact format of the recording depends on the target and binary file format. It usually takes the form of a section containing ASCII text ๐ค
This is related to -fverbose-asm, but that switch only records information in the assembler output file as comments, so it never reaches the object file ๐
โโ๏ธ. See also -grecord-gcc-switches for another way of storing compiler options into the object file ๐ธ
-fpicโ okay so this one spits out position-independent code (PIC) that's built for a shared library, if your target machine supports it ๐ All constant addresses go through a global offset table (GOT), and the dynamic loader fills in the GOT entries when the program starts. (The dynamic loader isn't part of GCC, it's part of the operating system ๐ง) If the GOT size for the linked executable goes over a machine-specific max, the linker throws an error saying-fpicdoesn't work, and then you recompile with-fPICinstead ๐ญ (The maxes are 8k on the SPARC, 28k on AArch64, and 32k on the m68k and RS/6000. The x86 has no such limit ๐ฆ)- Position-independent code needs special support, so it only works on certain machines. For the x86, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent ๐
- When this flag is set, the macros
__pic__and__PIC__are defined to 1 โจ
-fPICโ if the target machine supports it, this emits position-independent code that's ready for dynamic linking, and it dodges any limit on the size of the global offset table ๐ This option makes a difference on AArch64, m68k, PowerPC and SPARC.- Position-independent code needs special support, so it only works on certain machines.
- When this flag is set, the macros
__pic__and__PIC__are defined to 2 ๐
-fpie,-fPIEโ these are basically the same energy as-fpicand-fPIC, but the position-independent code can only be linked into executables ๐ Usually you'll use these to compile code that's getting linked with the-pieGCC option.- Both
-fpieand-fPIEdefine the macros__pie__and__PIE__. The macros have the value 1 for-fpieand 2 for-fPIE๐ธ
- Both
-fno-pltโ do not use the PLT for external function calls in position-independent code. Instead, load the callee address from the GOT at call sites and branch to it ๐ง This leads to more efficient code, because it gets rid of PLT stubs and exposes GOT loads to optimizations. On architectures like 32-bit x86, where PLT stubs expect the GOT pointer in a specific register, this gives the compiler more register allocation freedom ๐ฅ Lazy binding needs the PLT, so with-fno-pltall external symbols get resolved at load time.- Alternatively, the function attribute
nopltcan be used to avoid calls through the PLT for specific external functions ๐ - In position-dependent code, a few targets also convert calls to functions that are marked to not use the PLT so they use the GOT instead ๐ฆ
- Alternatively, the function attribute
-fno-jump-tablesโ no jump tables for switch statements, even in spots where they'd be more efficient than other code generation strategies ๐ This one is handy alongside-fpicor-fPICwhen you're building code that forms part of a dynamic linker and can't reference the address of a jump table. On some targets, jump tables don't need a GOT, so this option isn't needed there.-ffixed-regโ treat the register namedregas a fixed register, so generated code should never touch it (except maybe as a stack pointer, frame pointer, or in some other fixed role) ๐ซถreghas to be the name of a register. The accepted register names are machine-specific and get defined in theREGISTER_NAMESmacro in the machine description macro file.- This flag doesn't have a negative form, because it's a three-way choice โจ
-fcall-used-regโ treat the register namedregas an allocable register that gets clobbered by function calls. It can be allocated for temporaries or variables that don't live across a call. Functions compiled this way don't save and restore the registerreg๐- It's an error to use this flag with the frame pointer or stack pointer. Using it on other registers with fixed pervasive roles in the machine's execution model produces disastrous results ๐
- This flag doesn't have a negative form, because it specifies a three-way choice ๐ธ
-fcall-saved-regโ treat the register namedregas an allocable register that's saved by functions. It can be allocated even for temporaries or variables that live across a call. Functions compiled this way save and restore the registerregif they use it ๐- It's an error to use this flag with the frame pointer or stack pointer. Using it on other registers with fixed pervasive roles in the machine's execution model produces disastrous results ๐
- A different kind of disaster happens if you use this flag on a register where function values may be returned ๐ญ
- This flag doesn't have a negative form, because it specifies a three-way choice ๐
-fpack-struct[=n]โ without a value, this packs all structure members together with no holes ๐งฉ When you give a value (which has to be a small power of two), it packs structure members according to that value as the maximum alignment. Objects with default alignment requirements larger than this get output potentially unaligned at the next fitting location.
Warning: the -fpack-struct switch makes GCC generate code that isn't binary compatible with code generated without that switch ๐ It also makes the code suboptimal. Only use it to conform to a non-default application binary interface.
-fleading-underscoreโ this one and its counterpart,-fno-leading-underscore, forcibly change the way C symbols are represented in the object file ๐ฎ One use is helping you link with legacy assembly code.
Warning: the -fleading-underscore switch makes GCC generate code that isn't binary compatible with code generated without that switch ๐ Only use it to conform to a non-default application binary interface. Not all targets provide complete support for this switch.
-ftls-model=modelโ alter the thread-local storage model that gets used ๐ง Themodelargument should be one ofglobal-dynamic,local-dynamic,initial-execorlocal-exec. Note that the choice is subject to optimization: the compiler may use a more efficient model for symbols that aren't visible outside of the translation unit, or if-fpicisn't given on the command line ๐- The default without
-fpicisinitial-exec. With-fpic, the default isglobal-dynamicโจ
- The default without
-ftrampolinesโ for targets that normally need trampolines for nested functions, this always generates them instead of using descriptors ๐ Otherwise, targets that don't need them, like HP-PA or IA-64, do nothing.- A trampoline is a small piece of code that gets created at run time on the stack when the address of a nested function is taken, and it's used to call the nested function indirectly. Because of that, the stack has to be made executable for the program to work properly ๐ฌ
-fno-trampolinesis enabled by default on a language-by-language basis, so the compiler can skip generating them when it figures that's safe and swap them out for descriptors instead. Descriptors are made up of data only, but the generated code has to be prepared to deal with them. As of this writing,-fno-trampolinesis enabled by default only for Ada ๐- Code compiled with
-ftrampolinesand code compiled with-fno-trampolinesare not binary compatible if nested functions are present. This option has to be used on a program-wide basis and handled with extreme care ๐ซถ
-fvisibility=[default|internal|hidden|protected]โ sets the default ELF image symbol visibility to the option you pick, and all symbols get marked with it unless they're overridden in the code ๐ฆ Using this can substantially improve linking and load times of shared object libraries, produce more optimized code, give you near-perfect API export, and prevent symbol clashes. It's strongly recommended that you use this in any shared objects you distribute ๐- Despite the name,
defaultalways means public, i.e., available to be linked against from outside the shared object ๐ธprotectedandinternalare pretty useless in real-world usage, so the only other commonly used option ishidden. If-fvisibilityisn't specified, the default isdefault, meaning every symbol is public ๐ - For a good explanation of the benefits of making sure ELF symbols have the correct visibility, check out "How To Write Shared Libraries" by Ulrich Drepper, found at
https://www.akkadia.org/drepper/๐ A superior solution, made possible by this option, is to make the default hidden and mark things public instead of marking things hidden when the default is public. That's the norm with DLLs on Windows: with-fvisibility=hiddenand__attribute__ ((visibility("default")))instead of__declspec(dllexport), you get almost identical semantics with identical syntax. This is a great boon to anyone working on cross-platform projects ๐ - If you're adding visibility support to existing code,
#pragma GCC visibilitymight be your bestie ๐ You enclose the declarations you want to set visibility for with, for example,#pragma GCC visibility push(hidden)and#pragma GCC visibility pop. Bear in mind that symbol visibility should be treated as part of the API interface contract, so all new code should always specify visibility when it isn't the default. Declarations only for use within the local DSO should always be marked explicitly as hidden, to avoid PLT indirection overheads. Making this super clear also helps readability and self-documentation of the code ๐ง Note that because of ISO C++ specification requirements,operator newandoperator deletemust always be of default visibility. - Be aware that headers from outside your project, especially system headers and headers from any other library you use, may not be expecting to be compiled with visibility other than the default ๐ You may need to explicitly say
#pragma GCC visibility push(default)before including any of those headers.
- Despite the name,
extern declarations are totally unaffected by -fvisibility, so a ton of code can be recompiled with -fvisibility=hidden with zero changes ๐
โจ. Lowkey though, calls to extern functions with no explicit visibility still go through the PLT ๐, so it's way more effective to use __attribute ((visibility)) and/or #pragma GCC visibility to tell the compiler which extern declarations should be treated as hidden ๐ฅ.
Ngl, -fvisibility does affect C++ vague linkage entities ๐ง. That means an exception class that gets thrown between DSOs has to be explicitly marked with default visibility, so the type_info nodes get unified between the DSOs ๐.
An overview of these techniques, their benefits, and how to use them lives at http://gcc.gnu.org/wiki/Visibility ๐ฆ.
โจ -fstrict-volatile-bitfields โจ
Use this one if you want accesses to volatile bit-fields (or other structure fields, even though the compiler usually respects those types anyway) to be a single access at the width of the field's type, aligned to a natural alignment when that's possible ๐. For example, targets with memory-mapped peripheral registers might need every access to be 16 bits wide. With this flag you can declare all the peripheral bit-fields as unsigned short (assuming short is 16 bits on those targets) to force GCC to use 16-bit accesses, instead of a maybe-more-efficient 32-bit access ๐.
If this option is disabled, the compiler goes for the most efficient instruction. In the example above, that could be a 32-bit load instruction, even though it touches bytes that have no part of the bit-field in them, or memory-mapped registers unrelated to the one getting updated ๐ญ.
In some cases, like when the packed attribute is applied to a structure field, it might not be possible to access the field with a single read or write that's correctly aligned for the target machine. When that happens, GCC falls back to generating multiple accesses instead of code that would fault or truncate the result at run time ๐ซถ.
Note: Due to restrictions of the C/C++11 memory model, write accesses are not allowed to touch non bit-field members. So it's recommended to define all bits of the field's type as bit-field members ๐.
The default value of this option is determined by the application binary interface for the target processor ๐.
โจ -fsync-libcalls โจ
This option controls whether any out-of-line instance of the __sync family of functions may be used to implement the C++11 __atomic family of functions ๐ฅ.
The default is enabled, so the only useful form of the option is -fno-sync-libcalls ๐
. This option is used in the implementation of the libatomic runtime library ๐.
โจ GCC Developer Options โจ
This section is all about command-line options that are mainly for GCC developers, like options that support compiler testing and investigating compiler bugs and compile-time performance problems ๐ง. That includes options that produce debug dumps at various points in the compilation, options that print statistics like memory use and execution time, and options that print info about GCC's configuration, like where it searches for libraries ๐. You should rarely need any of these for ordinary compiling and linking, bestie ๐ซถ.
Lots of developer options that make GCC dump output to a file take an optional =filename suffix. You can specify stdout or - to dump to standard output, and stderr for standard error ๐ฆ.
If =filename is left off, a default dump file name gets built by concatenating the base dump file name, a pass number, a phase letter, and the pass name ๐. The base dump file name is the name of the output file the compiler produces if you explicitly specified one and it's not an executable. Otherwise, it's the source file name ๐. The pass number comes from the order passes are registered with the compiler's pass manager. That's usually the same as the order of execution, BUT passes registered by plugins, target-specific passes, or passes that are otherwise registered late get numbered higher than the pass named final, even if they run earlier ๐ญ. The phase letter is one of i (inter-procedural analysis), l (language-specific), r (RTL), or t (tree) โจ. The files are created in the directory of the output file ๐.
โจ -fcallgraph-info โจ
โจ -fcallgraph-info=MARKERS โจ
This makes the compiler output callgraph information for the program, on a per-object-file basis ๐ธ๏ธ. The information is generated in the common VCG format. You can decorate it with extra per-node and/or per-edge info by passing a list of comma-separated markers. When the su marker is specified, the callgraph gets decorated with stack usage information, which is equivalent to -fstack-usage ๐ฅ. When the da marker is specified, the callgraph gets decorated with info about dynamically allocated objects ๐
.
When compiling with -flto, no callgraph information is output along with the object file. At LTO link time, -fcallgraph-info may generate multiple callgraph information files next to the intermediate LTO output files ๐ธ.
โจ -dletters, -fdump-rtl-pass, -fdump-rtl-pass=filename โจ
This says to make debugging dumps during compilation at the times specified by the letters ๐. It's used for debugging the RTL-based passes of the compiler ๐.
Some -dletters switches mean something different when -E is used for preprocessing ๐.
Debug dumps can be enabled with a -fdump-rtl switch or with some -d option letters. Here are the possible letters for use in pass and letters, and what they mean ๐:
-fdump-rtl-alignmentsโ Dump after branch alignments have been computed. ๐-fdump-rtl-asmconsโ Dump after fixing RTL statements that have unsatisfied in/out constraints. ๐ ๏ธ-fdump-rtl-auto_inc_decโ Dump after auto-inc-dec discovery. This pass only runs on architectures that have auto inc or auto dec instructions. ๐ฏ-fdump-rtl-barriersโ Dump after cleaning up the barrier instructions. ๐งน-fdump-rtl-bbpartโ Dump after partitioning hot and cold basic blocks. ๐ฅโ๏ธ-fdump-rtl-bbroโ Dump after block reordering. ๐-fdump-rtl-btl1and-fdump-rtl-btl2โ these enable dumping after the two branch target load optimization passes. ๐-fdump-rtl-bypassโ Dump after jump bypassing and control flow optimizations. ๐ฆ-fdump-rtl-combineโ Dump after the RTL instruction combination pass. ๐งฉ-fdump-rtl-compgotosโ Dump after duplicating the computed gotos. ๐ญ-fdump-rtl-ce1,-fdump-rtl-ce2, and-fdump-rtl-ce3โ these enable dumping after the three if conversion passes. ๐-fdump-rtl-cprop_hardregโ Dump after hard register copy propagation. ๐-fdump-rtl-csaโ Dump after combining stack adjustments. ๐ฅ-fdump-rtl-cse1and-fdump-rtl-cse2โ these enable dumping after the two common subexpression elimination passes. ๐ฟ-fdump-rtl-dceโ Dump after the standalone dead code elimination passes. ๐๏ธ-fdump-rtl-dbrโ Dump after delayed branch scheduling. โณ-fdump-rtl-dce1and-fdump-rtl-dce2โ these enable dumping after the two dead store elimination passes. ๐-fdump-rtl-ehโ Dump after finalization of EH handling code. ๐-fdump-rtl-eh_rangesโ Dump after conversion of EH handling range regions. ๐-fdump-rtl-expandโ Dump after RTL generation. ๐ฑ-fdump-rtl-fwprop1and-fdump-rtl-fwprop2โ these enable dumping after the two forward propagation passes. โก๏ธ-fdump-rtl-gcse1and-fdump-rtl-gcse2โ these enable dumping after global common subexpression elimination. ๐-fdump-rtl-init-regsโ Dump after the initialization of the registers. ๐-fdump-rtl-initvalsโ Dump after the computation of the initial value sets. ๐งฎ-fdump-rtl-into_cfglayoutโ Dump after converting to cfglayout mode. ๐บ๏ธ-fdump-rtl-iraโ Dump after iterated register allocation. ๐-fdump-rtl-jumpโ Dump after the second jump optimization. ๐ฆ-fdump-rtl-loop2โ enables dumping after the RTL loop optimization passes. ๐-fdump-rtl-machโ Dump after performing the machine dependent reorganization pass, if that pass exists. โ๏ธ-fdump-rtl-mode_swโ Dump after removing redundant mode switches. ๐-fdump-rtl-rnregโ Dump after register renumbering. ๐ข-fdump-rtl-outof_cfglayoutโ Dump after converting from cfglayout mode. ๐บ๏ธ-fdump-rtl-peephole2โ Dump after the peephole pass. ๐-fdump-rtl-postreloadโ Dump after post-reload optimizations. ๐ง-fdump-rtl-pro_and_epilogueโ Dump after generating the function prologues and epilogues. ๐ฌ-fdump-rtl-sched1and-fdump-rtl-sched2โ these enable dumping after the basic block scheduling passes. ๐๏ธ-fdump-rtl-reeโ Dump after sign/zero extension elimination. ๐งฝ-fdump-rtl-seqabstrโ Dump after common sequence discovery. ๐-fdump-rtl-shortenโ Dump after shortening branches. ๐ฉณ-fdump-rtl-siblingโ Dump after sibling call optimizations. ๐ฏ-fdump-rtl-split1,-fdump-rtl-split2,-fdump-rtl-split3,-fdump-rtl-split4, and-fdump-rtl-split5โ these options enable dumping after five rounds of instruction splitting. โ๏ธ-fdump-rtl-smsโ Dump after modulo scheduling. This pass only runs on some architectures. ๐-fdump-rtl-stackโ Dump after conversion from GCC's "flat register file" registers to the x87's stack-like registers. This pass only runs on x86 variants. ๐ฅ-fdump-rtl-subreg1and-fdump-rtl-subreg2โ these enable dumping after the two subreg expansion passes. ๐งฌ-fdump-rtl-unshareโ Dump after all RTL has been unshared. ๐-fdump-rtl-vartrackโ Dump after variable tracking. ๐ต๏ธโโ๏ธ-fdump-rtl-vregsโ okay bestie, this one dumps right after virtual registers get converted to hard registers ๐-fdump-rtl-webโ dumps after live range splitting โจ-fdump-rtl-regclass,-fdump-rtl-subregs_of_mode_init,-fdump-rtl-subregs_of_mode_finish,-fdump-rtl-dfinit,-fdump-rtl-dfinishโ these are defined but always produce empty files ๐ so don't get your hopes up, bestie-da,-fdump-rtl-allโ produces all the dumps listed above ๐-dAโ annotates the assembler output with miscellaneous debugging info ๐-dDโ dumps all macro definitions at the end of preprocessing, in addition to the normal output ๐ง-dHโ produces a core dump whenever an error occurs ๐-dpโ annotates the assembler output with a comment saying which pattern and alternative got used ๐ฆ It also prints the length and cost of each instruction, which is lowkey iconic-dPโ dumps the RTL in the assembler output as a comment before each instruction ๐ It also turns on-dpannotation, so you get both-dxโ just generates RTL for a function instead of fully compiling it ๐ This is usually paired with-fdump-rtl-expand
-fdump-debugโ dumps the debugging info generated during the debug generation phase ๐ซถ-fdump-earlydebugโ dumps the debugging info generated during the early debug generation phase ๐ธ-fdump-noaddrโ when doing debugging dumps, this suppresses address output ๐ That makes it way easier todiffdumps from different compiler binaries and/or different text / bss / data / heap / stack / dso start locations-freport-bugโ if an internal compiler error (ICE) happens, this collects and dumps debug info into a temporary file ๐ญ bestie, the compiler is literally helping you report the bug-fdump-unnumberedโ when doing debugging dumps, this suppresses instruction numbers and address output โจ It makesdiffway more feasible for compiler invocations with different options, especially with and without-g-fdump-unnumbered-linksโ when doing debugging dumps (see the-doption above), this suppresses instruction numbers for the links to the previous and next instructions in a sequence ๐ฆ
-fdump-ipa-switch,-fdump-ipa-switch-optionsโ okay so these control dumping at various stages of inter-procedural analysis language tree to a file ๐ The file name is made by appending a switch-specific suffix to the source file name, and it gets created in the same directory as the output file. Here are the dumps you can ask for:allโ enables all inter-procedural analysis dumps ๐ฅcgraphโ dumps info about call-graph optimization, unused function removal, and inlining decisions ๐inlineโ dumps after function inlining ๐ง
You can also add -optimized, -missed, -note, and -all, which mean the same thing as they do for -fopt-info. It defaults to -optimized.
For example, -fdump-ipa-inline-optimized-missed will show you the callsites that got inlined and the ones that didn't. Main character energy ๐
By default, the dump has messages about successful optimizations (same as -optimized) along with the low-level details of the analysis ๐
-fdump-lang-all,-fdump-lang-switch,-fdump-lang-switch-options,-fdump-lang-switch-options=filenameโ these control dumping of language-specific info ๐ The options and filename bits work the same way as in the-fdump-treeoption. The switch values you can use are:allโ enables all language-specific dumps ๐ธclassโ dumps class hierarchy info ๐ฆ Virtual table info gets emitted unless you say'slim'. This one is for C++ onlyrawโ dumps the raw internal tree data ๐ This one is also C++ only
-fdump-passesโ prints the list of optimization passes that are turned on and off by your current command-line options to stderr ๐ง-fdump-statistics-optionโ enables and controls dumping of pass statistics into a separate file โจ The file name is made by appending a suffix ending in.statisticsto the source file name, and it lands in the same directory as the output file. If you use the-optionform,-statssums the counters over the whole compilation unit, while-detailsdumps every event as the passes generate it. With no option, the default is to sum counters for each function compiled ๐
-fdump-tree-all,-fdump-tree-switch,-fdump-tree-switch-options,-fdump-tree-switch-options=filenameโ this controls the dumping at various stages of processing the intermediate language tree to a file ๐ซถ If you use the-optionsform,optionsis a list of-separated options that control the details of the dump. Not every option works with every dump, and the ones that don't make sense just get ignored. Here's what's available:addressโ prints the address of each node ๐ Usually this isn't meaningful since it changes with the environment and source file. Its main use is tying a dump file to a debug environmentasmnameโ if"DECL_ASSEMBLER_NAME"has been set for a decl, uses that in the dump instead of"DECL_NAME"๐ Its main use is working backward from mangled names in the assembly fileslimโ when dumping front-end intermediate representations, stops members of a scope or body of a function from being dumped just because that scope was reached. Only items directly reachable by some other path get dumped ๐ When dumping pretty-printed trees, this skips the bodies of control structures. When dumping RTL, it prints the RTL in slim (condensed) form instead of the default LISP-like representationrawโ prints a raw representation of the tree ๐ By default, trees are pretty-printed into a C-like representationdetailsโ enables more detailed dumps (not every dump option honors this) and includes info from the optimization passes ๐ฅstatsโ enables dumping various statistics about the pass (again, not every dump option honors this) ๐blocksโ enables showing basic block boundaries (disabled in raw dumps) ๐งgraphโ for each of the other indicated dump files (-fdump-rtl-pass), dumps a control flow graph representation suitable for viewing with GraphViz tofile.passid.pass.dot๐ฆ Each function gets pretty-printed as a subgraph, so GraphViz can render them all in one plot. This only works for RTL dumps, and the RTL is always dumped in slim formvopsโ enables showing virtual operands for every statement ๐linenoโ enables showing line numbers for statements ๐ธuidโ enables showing the unique ID ("DECL_UID") for each variable โจverboseโ enables showing the tree dump for each statement ๐ehโ enables showing the EH region number holding each statement ๐ซถscevโ enables showing scalar evolution analysis details ๐optimizedโ enables showing optimization info (only in certain passes) ๐missedโ enables showing missed optimization info (only in certain passes) ๐noteโ enables other detailed optimization info (only in certain passes) ๐allโ turns on all options, exceptraw,slim,verbose, andlineno๐optallโ turns on all optimization options, i.e.,optimized,missed, andnote๐ฅ
Okay, so if you want to figure out which tree dumps exist or find the dump for a pass you care about, follow these steps:
- Invoke GCC with
-fdump-passesand look in the stderr output for a code that matches the pass you want. For example, the codes"tree-evrp","tree-vrp1", and"tree-vrp2"correspond to the three Value Range Propagation passes. The number at the end tells apart the different invocations of the same pass ๐ง - To enable the dump file, append the pass code to the
-fdump-option prefix and invoke GCC with it ๐ For example, to get the dump from the Early Value Range Propagation pass, invoke GCC with the-fdump-tree-evrpoption. You can optionally name the dump file yourself. If you don't, GCC makes one as described below - Find the pass dump in a file whose name has three parts separated by periods: the name of the source file GCC was invoked to compile, a numeric suffix for the pass number followed by the letter
tfor tree passes (and the letterrfor RTL passes), and finally the pass code ๐ฆ For example, the Early VRP pass dump might be in a file namedmyfile.c.038t.evrpin the current working directory
โ ๏ธ Heads up, bestie: the numeric codes are not stable and may change from one version of GCC to another ๐
-fopt-info,-fopt-info-options,-fopt-info-options=filenameโ controls optimization dumps from the various optimization passes ๐ If you use the-optionsform,optionsis a list of-separated option keywords that pick the dump details and optimizations
The options split into three groups, and it's giving organized ๐ซถ
- options describing what kinds of messages should be emitted,
- options describing the verbosity of the dump, and
- options describing which optimizations should be included.
You can mix the options from each group freely since they don't overlap. If there's ever a conflict, the later options on the command line win ๐
These options control which kinds of messages get emitted:
optimizedโ prints info when an optimization is successfully applied โจ It's up to each pass to decide what's relevant. For example, the vectorizer passes print the source location of loops that got successfully vectorized ๐ฅmissedโ prints info about missed optimizations ๐ Individual passes control what info goes in the output
noteโ ๐ bestie, this one prints verbose info about optimizations, like certain transformations and more detailed messages about the decisions GCC makes. Main character info ๐allโ ๐ฅ prints the detailed optimization info, and that includesoptimized,missed, andnoteall together. Everything, no cap โจ
The following option controls the dump verbosity:
internalsโ ๐ค by default, only the "high-level" messages show up. This turns on the extra, more detailed messages, which are probably only interesting to GCC developers ๐
One or more of the following option keywords can be used to describe a group of optimizations:
ipaโ ๐งฉ enables dumps from all interprocedural optimizations.loopโ ๐ enables dumps from all loop optimizations.inlineโ ๐ฆ enables dumps from all inlining optimizations.ompโ ๐ enables dumps from all OMP (Offloading and Multi Processing) optimizations.vecโ ๐ฆ enables dumps from all vectorization optimizations.optallโ ๐ enables dumps from all optimizations. It's a superset of the optimization groups listed above, so it's giving everything.
If options is omitted, it defaults to optimized-optall. That means you get messages about successful optimizations from all the passes, and anything treated as "internals" gets left out ๐ธ
If the filename is provided, the dumps from all the applicable optimizations get concatenated into that file. Otherwise, the dump is output onto stderr ๐ Though multiple -fopt-info options are accepted, only one of them can include a filename. If other filenames are provided, then all but the first such option are ignored ๐
Note that the output filename is overwritten in case of multiple translation units. If you want a combined output from multiple translation units, use stderr instead. ๐
In the following example, the optimization info is output to stderr:
gcc -O3 -fopt-info
This example:
gcc -O3 -fopt-info-missed=missed.all
outputs the missed optimization report from all the passes into missed.all, and this one:
gcc -O2 -ftree-vectorize -fopt-info-vec-missed
prints information about missed optimization opportunities from vectorization passes on stderr. Note that -fopt-info-vec-missed is equivalent to -fopt-info-missed-vec. The order of the optimization group names and message types listed after -fopt-info does not matter ๐ฆ
As another example:
gcc -O3 -fopt-info-inline-optimized-missed=inline.txt
outputs information about missed optimizations, as well as optimized locations, from all the inlining passes into inline.txt ๐ฆ
Finally, consider:
gcc -fopt-info-vec-missed=vec.miss -fopt-info-loop-optimized=loop.opt
Here the two output filenames vec.miss and loop.opt are in conflict, since only one output file is allowed. In this case, only the first option takes effect and the subsequent options are ignored. Thus only vec.miss is produced, which contains dumps from the vectorizer about missed opportunities ๐ญ
-fsave-optimization-record
โจ This writes a SRCFILE.opt-record.json.gz file detailing what optimizations were performed, for the ones that support -fopt-info.
This option is experimental, and the format of the data within the compressed JSON file is subject to change. โ ๏ธ
It's roughly a machine-readable version of -fopt-info-all, as a collection of messages with source file, line number and column number. Each message also comes with these extra bits:
- the execution count of the code being optimized, plus metadata about whether that came from actual profile data or just an estimate, so you can prioritize messages by code hotness ๐ฅ
- the function name of the code being optimized, where applicable ๐ง
- the "inlining chain" for the code being optimized, so when a function is inlined into several different places (which might themselves be inlined), you can tell the copies apart ๐ช
- objects identifying those parts of the message that refer to expressions, statements or symbol-table nodes, which of these categories they are, and, when available, their source code location ๐ซถ
- the GCC pass that emitted the message, and
- the location in GCC's own code from which the message was emitted
Additionally, some messages are logically nested within other messages, reflecting implementation details of the optimization passes ๐
-fsched-verbose=n
On targets that use instruction scheduling, this option controls how much debugging output the scheduler prints to the dump files ๐
For n greater than zero, -fsched-verbose outputs the same information as -fdump-rtl-sched1 and -fdump-rtl-sched2. For n greater than one, it also outputs basic block probabilities, detailed ready list information and unit/insn info. For n greater than two, it includes RTL at abort point, control-flow and regions info. And for n over four, -fsched-verbose also includes dependence info ๐
-fenable-kind-pass, -fdisable-kind-pass=range-list
This is a set of options used to explicitly disable or enable optimization passes. They're intended for debugging GCC ๐ ๏ธ Compiler users should use the regular options for enabling and disabling passes instead, bestie ๐
-fdisable-ipa-passโ disables IPA pass pass. pass is the pass name. If the same pass is statically invoked in the compiler multiple times, the pass name should be appended with a sequential number starting from 1.-fdisable-rtl-pass,-fdisable-rtl-pass=range-listโ disables RTL pass pass. pass is the pass name. If the same pass is statically invoked in the compiler multiple times, the pass name should be appended with a sequential number starting from 1. range-list is a comma-separated list of function ranges or assembler names. Each range is a number pair separated by a colon, and the range is inclusive at both ends. If the range is trivial, the number pair can be simplified to a single number. If the function's call graph node's uid falls within one of the specified ranges, the pass is disabled for that function. The uid is shown in the function header of a dump file, and the pass names can be dumped by using option-fdump-passes๐-fdisable-tree-pass,-fdisable-tree-pass=range-listโ disables tree pass pass. See-fdisable-rtlfor the description of option arguments.-fenable-ipa-passโ enables IPA pass pass. pass is the pass name. If the same pass is statically invoked in the compiler multiple times, the pass name should be appended with a sequential number starting from 1.-fenable-rtl-pass,-fenable-rtl-pass=range-listโ enables RTL pass pass. See-fdisable-rtlfor option argument description and examples.-fenable-tree-pass,-fenable-tree-pass=range-listโ enables tree pass pass. See-fdisable-rtlfor the description of option arguments.
Here are some examples showing uses of these options ๐
# disable ccp1 for all functions
-fdisable-tree-ccp1
# disable complete unroll for function whose cgraph node uid is 1
-fenable-tree-cunroll=1
# disable gcse2 for functions at the following ranges [1,1],
# [300,400], and [400,1000]
# disable gcse2 for functions foo and foo2
-fdisable-rtl-gcse2=foo,foo2
# disable early inlining
-fdisable-tree-einline
# disable ipa inlining
-fdisable-ipa-inline
# enable tree full unroll
-fenable-tree-unroll
-fchecking, -fchecking=n
โ
This enables internal consistency checking. The default depends on the compiler configuration. -fchecking=2 enables further internal consistency checking that might affect code generation, so be careful with that one ๐
-frandom-seed=string
๐ฒ This option provides a seed that GCC uses in place of random numbers when generating certain symbol names that have to be different in every compiled file. It's also used to place unique stamps in coverage data files and the object files that produce them. You can use -frandom-seed to produce reproducibly identical object files, which is so satisfying ๐ฅน
The string can either be a number (decimal, octal or hex) or an arbitrary string. If it's an arbitrary string, it gets converted to a number by computing CRC32 ๐ข
The string should be different for every file you compile ๐ซถ
-save-temps, -save-temps=cwd
๐พ This stores the usual "temporary" intermediate files permanently. It places them in the current directory and names them based on the source file. So compiling foo.c with -c -save-temps produces files foo.i and foo.s, as well as foo.o. This creates a preprocessed foo.i output file, even though the compiler now normally uses an integrated preprocessor ๐ง
When it's used in combination with the -x command-line option, -save-temps is sensible enough to avoid overwriting an input source file that has the same extension as an intermediate file. The corresponding intermediate file can be obtained by renaming the source file before using -save-temps ๐ง
If you invoke GCC in parallel, compiling several different source files that share a common base name in different subdirectories, or the same source file compiled for multiple output destinations, the parallel compilers will probably interfere with each other and overwrite the temporary files. For instance:gcc -save-temps -o outdir1/foo.o indir1/foo.c& gcc -save-temps -o outdir2/foo.o indir2/foo.c&may result infoo.iandfoo.obeing written to simultaneously by both compilers. ๐ฑ
-save-temps=obj
๐ This stores the usual "temporary" intermediate files permanently. If the -o option is used, the temporary files are based on the object file. If the -o option is not used, the -save-temps=obj switch behaves like -save-temps ๐ฆ
For example:
gcc -save-temps=obj -c foo.c
gcc -save-temps=obj -c bar.c -o dir/xbar.o
gcc -save-temps=obj foobar.c -o dir2/yfoobar
creates foo.i, foo.s, dir/xbar.i, dir/xbar.s, dir2/yfoobar.i, dir2/yfoobar.s, and dir2/yfoobar.o. ๐ธ
-time[=file]โ okay bestie, this one is a stopwatch for every little subprocess in the compile chain โฑ๏ธ ๐ For C source files, that's the compiler proper and the assembler (plus the linker too, if you're linking).
Without an output file, you get something like this:
# cc1 0.12 0.01
# as 0.00 0.01
The first number on each line is the "user time", which is how long the program was actually running its own code. The second number is the "system time", which is time spent in operating system routines on the program's behalf. Both are in seconds โจ
With an output file, the info gets appended to that named file, and it looks like this:
0.12 0.01 cc1 <options>
0.00 0.01 as <options>
Now the "user time" and "system time" get moved in front of the program name, and the options passed to the program are shown too ๐ง So later you can totally tell what file was being compiled and with which options. Main character record-keeping, iykyk ๐
-fdump-final-insns[=file]โ dumps the final internal representation (RTL) intofile๐ฆ If you leave off the optional argument (or the file is.), the dump file gets named by slapping.gkdonto the end of the compilation output file name.-fcompare-debug[=opts]โ this one is giving double-check energy ๐ฅ If nothing errors during compilation, the compiler runs a second time withoptsand-fcompare-debug-secondadded to the arguments for that second go. It dumps the final internal representation in both runs and prints an error if they don't match ๐
If you skip the equal sign, the default -gtoggle gets used.
The environment variable GCC_COMPARE_DEBUG works as a sneaky switch: if it's defined, non-empty, and nonzero, it implicitly turns on -fcompare-debug ๐ If GCC_COMPARE_DEBUG is set to a string starting with a dash, that string becomes opts. Otherwise the default -gtoggle is used.
-fcompare-debug=, with the equal sign but no opts, is the same as -fno-compare-debug. That one turns off the dumping of the final representation and the second compilation, and it even stops GCC_COMPARE_DEBUG from taking effect ๐
To check full coverage while testing -fcompare-debug, set GCC_COMPARE_DEBUG to say -fcompare-debug-not-overridden. GCC rejects that as an invalid option in any real compilation (as opposed to preprocessing, assembly, or linking). If you only want a warning instead, setting GCC_COMPARE_DEBUG to -w%n-fcompare-debug not overridden will do the trick ๐
-fcompare-debug-secondโ this one is passed to the compiler automatically for that second compilation kicked off by-fcompare-debug๐ซถ It comes along with options that silence warnings, and it leaves out any other options that would make the compiler write output to files or standard output as a side effect. Dump files and preserved temporary files get renamed to carry an extra.gkextension during the second compilation, so they don't overwrite the ones from the first run ๐ธ
When you hand this option to the compiler driver, it makes the first compilation get skipped entirely. So it's pretty much only useful for debugging the compiler itself ๐ค
-gtoggleโ flips debug info on or off ๐ If leaving out this option would generate debug info, it turns generation off. Otherwise it turns it on at level 2. Where you put it in the command line doesn't matter. It takes effect after all the other options are processed, and it only does its thing once, no matter how many times you type it โจ It's mainly meant to be used with-fcompare-debug.-fvar-tracking-assignments-toggleโ toggles-fvar-tracking-assignmentsin the same way-gtoggletoggles-g๐-Qโ makes the compiler print out each function name as it gets compiled, and print some stats about each pass once it's done ๐ฆ-ftime-reportโ the compiler prints some stats about the time each pass ate up when it finishes โฐ-ftime-report-detailsโ records the time consumed by infrastructure parts separately for each pass ๐งฉ-fira-verbose=nโ controls how chatty the dump file for the integrated register allocator is ๐ฃ๏ธ The default value is5. Ifnis10or higher, the dump output gets sent to stderr, using the same format asnminus 10.-flto-reportโ prints a report with internal details on how the link-time optimizer is working ๐ The contents of this report change from version to version. It's meant to be useful to GCC developers when they're processing object files in LTO mode (via-flto). It's disabled by default, so you have to ask for it ๐-flto-report-wpaโ same as-flto-report, but only prints for the WPA phase of link-time optimization ๐-fmem-reportโ the compiler prints some stats about permanent memory allocation when it finishes ๐ง-fmem-report-wpaโ prints stats about permanent memory allocation for the WPA phase only ๐ซง-fpre-ipa-mem-report,-fpost-ipa-mem-reportโ prints some stats about permanent memory allocation either before or after interprocedural optimization ๐-fprofile-reportโ prints some stats about how consistent the (estimated) profile is, and what effect each individual pass had ๐-fstack-usageโ this one is giving stack receipts ๐งพ The compiler outputs stack usage info for the program, per function. The dump filename is made by tacking.suonto theauxname. Theauxnamecomes from the output file name if you explicitly specified one and it's not an executable. Otherwise, it's the basename of the source file. Each entry has three fields:- The name of the function.
- A number of bytes.
- One or more qualifiers:
"static","dynamic","bounded".
The "static" qualifier means the function handles the stack in a fixed way: a set number of bytes gets allocated for the frame on function entry and released on function exit. No other stack adjustments get made in the function. The second field is that fixed number of bytes ๐ฟ
The "dynamic" qualifier means the function also moves the stack around as it goes. On top of the static allocation, there are stack adjustments made in the body of the function, like pushing and popping arguments around function calls ๐ญ If "bounded" is also there, the amount of those adjustments is bounded at compile time, and the second field is an upper bound on the total stack used by the function. If "bounded" isn't there, the adjustments aren't bounded at compile time, and the second field only covers the bounded part.
-fstatsโ emits stats about front-end processing at the end of the compilation ๐ This only works with the C++ front end, and the info is generally only useful to the G++ development team, so it's kind of a behind-the-scenes thing ๐-fdbg-cnt-listโ prints the name and the counter upper bound for every debug counter ๐ข-fdbg-cnt=counter-value-listโ sets the internal debug counter lower and upper bounds ๐ฏ Thecounter-value-listis a comma-separated list ofname:lower_bound1-upper_bound1 [:lower_bound2-upper_bound2...]tuples. Each one sets the counter's name and a list of closed intervals. Thelower_boundis optional, and it's zero-initialized if it isn't set. For example, with-fdbg-cnt=dce:2-4:10-11,tail_call:10,"dbg_cnt(dce)"returns true only for the second, third, fourth, tenth, and eleventh invocation. For"dbg_cnt(tail_call)", true is returned for the first 10 invocations โจ
-print-file-name=libraryโ prints the full absolute name of thelibraryfile that would be used when linking, and that's it ๐บ๏ธ With this option, GCC doesn't compile or link anything. It just prints the file name.-print-multi-directoryโ prints the directory name for the multilib picked by any other switches in the command line ๐ That directory is supposed to exist inGCC_EXEC_PREFIX.-print-multi-libโ prints the mapping from multilib directory names to the compiler switches that enable them ๐๏ธ The directory name is separated from the switches by;. Each switch starts with@instead of-, with no spaces between multiple switches. This is supposed to make shell processing easier ๐-print-multi-os-directoryโ prints the path to OS libraries for the selected multilib, relative to somelibsubdirectory ๐ If OS libraries are in thelibsubdirectory and no multilibs are used, this is usually just.. If OS libraries are inlibsuffixsibling directories, it prints something like../lib64,../lib, or../lib32. If OS libraries are inlib/subdirsubdirectories, it prints something likeamd64,sparcv9, orev6๐-print-multiarchโ prints the path to OS libraries for the selected multiarch, relative to somelibsubdirectory ๐น-print-prog-name=programโ like-print-file-name, but it searches for a program such ascppinstead ๐-print-libgcc-file-nameโ same as-print-file-name=libgcc.a๐
This is handy when you use -nostdlib or -nodefaultlibs but you still want to link with libgcc.a. You can do:
gcc -nostdlib <files>... `gcc -print-libgcc-file-name`
-print-search-dirsโ prints the name of the configured installation directory, plus a list of the program and library directories gcc searches. Then it stops, and doesn't do anything else ๐ต๏ธ
This is useful when gcc prints the error message installation problem, cannot exec cpp0: No such file or directory. ๐ฑ To fix that, you either need to put cpp0 and the other compiler components where gcc expects to find them, or you can set the environment variable GCC_EXEC_PREFIX to the directory where you installed them. Don't forget the trailing /! ๐ซถ
-print-sysrootโ prints the target sysroot directory used during compilation ๐ This is the target sysroot specified either at configure time or with the--sysrootoption, possibly with an extra suffix that depends on compilation options. If no target sysroot is specified, this option prints nothing.-print-sysroot-headers-suffixโ prints the suffix added to the target sysroot when searching for headers. If the compiler isn't configured with such a suffix, it gives an error instead. Either way, it doesn't do anything else ๐
-dumpmachineโ okay so this one prints the compiler's target machine, likei686-pc-linux-gnu` ๐ฅ๏ธ, and then it literally does nothing else ๐
-dumpversionโ prints the compiler version (like3.0,6.3.0or7) and then stops right there ๐. This is the version that shows up in filesystem paths and specs, so it's doing important behind-the-scenes work ๐ซถ. Depending on how the compiler was configured, it might be one number (major version), two numbers separated by a dot (major and minor version), or three numbers separated by dots (major, minor and patchlevel version) โจ.-dumpfullversionโ prints the full compiler version and nothing else ๐ฆ. The output is always three numbers separated by dots: major, minor and patchlevel version ๐ฅ.-dumpspecsโ prints the compiler's built-in specs and then stops ๐ธ. (This one is used when GCC itself is being built, so it's giving insider build-system info ๐.)
๐ Machine-Dependent Options ๐
Each target machine GCC supports can have its own options ๐. Like, you might want to compile for a particular processor variant or ABI, or control optimizations that are specific to that machine โจ. By convention, the names of machine-specific options start with -m ๐ง.
Some configurations of the compiler also support extra target-specific options, usually so they stay compatible with other compilers on the same platform ๐ซถ.
๐ AArch64 Options ๐
These options are defined for AArch64 implementations ๐ฆ:
-mabi=nameโ generates code for the data model you pick ๐. The valid values areilp32, which is SysV-like withint,long intand pointers all at 32 bits, andlp64, which is SysV-like withintat 32 bits butlong intand pointers at 64 bits ๐ . The default depends on the specific target configuration.
โ ๏ธ Heads up bestie: the LP64 and ILP32 ABIs are not link-compatible ๐. You have to compile your entire program with the same ABI and link it with a compatible set of libraries, or things get messy fr fr.
-mbig-endianโ generates big-endian code ๐. This is the default when GCC is configured for anaarch64_be-*-*target.-mgeneral-regs-onlyโ generates code that only uses the general-purpose registers ๐ธ. This stops the compiler from using floating-point and Advanced SIMD registers, but it doesn't put any restrictions on the assembler.-mlittle-endianโ generates little-endian code ๐. This is the default when GCC is configured for anaarch64-*-*target but not anaarch64_be-*-*target.-mcmodel=tinyโ generates code for the tiny code model ๐ง. The program and its statically defined symbols must be within 1MB of each other. Programs can be statically or dynamically linked.-mcmodel=smallโ generates code for the small code model โจ. The program and its statically defined symbols must be within 4GB of each other. Programs can be statically or dynamically linked. This is the default code model, so you're already slaying with it ๐.-mcmodel=largeโ generates code for the large code model ๐ฆ. It makes no assumptions about addresses and sizes of sections. Programs can be statically linked only. This option is incompatible with-mabi=ilp32,-fpicand-fPIC๐.-mstrict-align,-mno-strict-alignโ avoids or allows generating memory accesses that may not be aligned on a natural object boundary, as described in the architecture specification ๐ฅ.-momit-leaf-frame-pointer,-mno-omit-leaf-frame-pointerโ omits or keeps the frame pointer in leaf functions ๐. The former behavior is the default.-mstack-protector-guard=guard,-mstack-protector-guard-reg=reg,-mstack-protector-guard-offset=offsetโ generates stack protection code using a canary at guard ๐ก๏ธ. The supported locations areglobalfor a global canary orsysregfor a canary in an appropriate system register.
With the latter choice, the options -mstack-protector-guard-reg=reg and -mstack-protector-guard-offset=offset furthermore specify which system register to use as the base register for reading the canary, and from what offset from that base register ๐
. There is no default register or offset, because this is entirely for use within the Linux kernel ๐.
-mstack-protector-guard=guard,-mstack-protector-guard-reg=reg,-mstack-protector-guard-offset=offsetโ generates stack protection code using a canary at guard ๐ก๏ธ. The supported locations areglobalfor a global canary orsysregfor a canary in an appropriate system register.
With the latter choice, the options -mstack-protector-guard-reg=reg and -mstack-protector-guard-offset=offset furthermore specify which system register to use as the base register for reading the canary, and from what offset from that base register ๐
. There is no default register or offset, because this is entirely for use within the Linux kernel ๐.
-mtls-dialect=descโ uses TLS descriptors as the thread-local storage mechanism for dynamic accesses of TLS variables ๐. This is the default.-mtls-dialect=traditionalโ uses traditional TLS as the thread-local storage mechanism for dynamic accesses of TLS variables ๐ธ.-mtls-size=sizeโ specifies the bit size of immediate TLS offsets โจ. Valid values are12,24,32and48. This option requires binutils 2.26 or newer, so check your toolchain first ๐ซถ.-mfix-cortex-a53-835769,-mno-fix-cortex-a53-835769โ enables or disables the workaround for the ARM Cortex-A53 erratum number 835769 ๐ง. It works by inserting a NOP instruction between memory instructions and 64-bit integer multiply-accumulate instructions.-mfix-cortex-a53-843419,-mno-fix-cortex-a53-843419โ enables or disables the workaround for the ARM Cortex-A53 erratum number 843419 ๐ง. This erratum workaround is made at link time, so this option only passes the corresponding flag to the linker ๐.-mlow-precision-recip-sqrt,-mno-low-precision-recip-sqrtโ enables or disables the reciprocal square root approximation ๐งฎ. This option only has an effect if-ffast-mathor-funsafe-math-optimizationsis used as well. Enabling it reduces the precision of reciprocal square root results to about 16 bits for single precision and to 32 bits for double precision.-mlow-precision-sqrt,-mno-low-precision-sqrtโ enables or disables the square root approximation ๐งฎ. This option only has an effect if-ffast-mathor-funsafe-math-optimizationsis used as well. Enabling it reduces the precision of square root results to about 16 bits for single precision and to 32 bits for double precision. If enabled, it implies-mlow-precision-recip-sqrt.-mlow-precision-div,-mno-low-precision-divโ enables or disables the division approximation โ. This option only has an effect if-ffast-mathor-funsafe-math-optimizationsis used as well. Enabling it reduces the precision of division results to about 16 bits for single precision and to 32 bits for double precision.-mtrack-speculation,-mno-track-speculationโ enables or disables generation of additional code that tracks speculative execution through conditional branches ๐. The tracking state can then be used by the compiler when expanding calls to"__builtin_speculation_safe_copy", so it can generate a more efficient code sequence.-moutline-atomics,-mno-outline-atomicsโ enables or disables calls to out-of-line helpers that implement atomic operations โ๏ธ. These helpers figure out at runtime whether the LSE instructions from ARMv8.1-A can be used. If they can't, they fall back to the load/store-exclusive instructions that are present in the base ARMv8.0 ISA.
This option is only applicable when compiling for the base ARMv8.0 instruction set ๐. If you're using a later revision, e.g. -march=armv8.1-a or -march=armv8-a+lse, the ARMv8.1-Atomics instructions will be used directly. The same applies when using -mcpu= when the selected CPU supports the lse feature. This option is on by default ๐.
-march=nameโ specifies the name of the target architecture and, optionally, one or more feature modifiers ๐๏ธ. This option has the form-march=arch{+[no]feature}*.
Here's the vibe check on what each arch value gives you, and the features it turns on by default:
armv8-a(Armv8-A) โ includes by default+fp, +simdarmv8.1-a(Armv8.1-A) โ includes by defaultarmv8-a, +crc, +lse, +rdmaarmv8.2-a(Armv8.2-A) โ includes by defaultarmv8.1-aarmv8.3-a(Armv8.3-A) โ includes by defaultarmv8.2-aarmv8.4-a(Armv8.4-A) โ includes by defaultarmv8.3-a, +fp16fml, +dotprodarmv8.5-a(Armv8.5-A) โ includes by defaultarmv8.4-a, +sb, +ssbs, +predresarmv8.6-a(Armv8.6-A) โ includes by defaultarmv8.5-a, +bf16, +i8mm
The value native is available on native AArch64 GNU/Linux ๐ฅ๏ธ and makes the compiler pick the architecture of the host system. This option has no effect if the compiler is unable to recognize the architecture of the host system,
The permissible values for feature are listed in the sub-section aarch64-feature-modifiers,,-march and -mcpu Feature Modifiers. Where conflicting feature modifiers are specified, the right-most feature is used ๐.
GCC uses name to determine what kind of instructions it can emit when generating assembly code ๐ง . If -march is specified without either -mtune or -mcpu also being specified, the code is tuned to perform well across a range of target processors implementing the target architecture โจ.
-mtune=nameโ specifies the name of the target processor that GCC should tune the performance of the code for ๐ฏ. The permissible values for this option are:generic,cortex-a35,cortex-a53,cortex-a55,cortex-a57,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a65,cortex-a65ae,cortex-a34,ares,exynos-m1,emag,falkor,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,neoverse-512tvb,qdf24xx,saphira,phecda,xgene1,vulcan,octeontx,octeontx81,octeontx83,octeontx2,octeontx2t98,octeontx2t96 octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,thunderx,thunderxt88,thunderxt88p1,thunderxt81,tsv110,thunderxt83,thunderx2t99,thunderx3t110,zeus,cortex-a57.cortex-a53,cortex-a72.cortex-a53,cortex-a73.cortex-a35,cortex-a73.cortex-a53,cortex-a75.cortex-a55,cortex-a76.cortex-a55,ampere1,ampere1a,native.
The values cortex-a57.cortex-a53, cortex-a72.cortex-a53, cortex-a73.cortex-a35, cortex-a73.cortex-a53, cortex-a75.cortex-a55 and cortex-a76.cortex-a55 tell GCC to tune for a big.LITTLE system ๐ฆ๐.
okay so the neoverse-512tvb value is giving very specific ๐ฆ. It tells GCC to tune for Neoverse cores that (a) implement SVE and (b) have a total vector bandwidth of 512 bits per cycle. Basically, these cores can run 4 128-bit Advanced SIMD arithmetic instructions a cycle, and they can run an equal number of SVE arithmetic instructions per cycle too (2 for 256-bit SVE, 4 for 128-bit SVE) ๐
. It's more general than tuning for one specific core like Neoverse V1, but it's more specific than the default tuning we'll get to below ๐ธ.
Also, on native AArch64 GNU/Linux systems, native tunes performance to whatever host you're on โจ. If the compiler can't recognize your host's processor, this option just does nothing ๐.
Where none of -mtune=, -mcpu= or -march= are specified, the code is tuned to perform well across a whole range of target processors ๐.
This option cannot be suffixed by feature modifiers ๐ซ.
๐ -mcpu=name
Name the target processor, and optionally slap one or more feature modifiers on the end ๐
. The form is -mcpu=cpu{+[no]feature}*. The values allowed for cpu are the same ones you get with -mtune, and you can check the feature modifiers in the sub-section on aarch64-feature-modifiers,,-march and -mcpu Feature Modifiers. If you give conflicting feature modifiers, the right-most one wins ๐.
GCC uses name to figure out what kinds of instructions it's allowed to emit when it writes assembly (same as -march), and which processor to tune performance for (same as -mtune) โจ. If you use this option alongside -march or -mtune, those two win for their part of the job ๐ซถ.
-mcpu=neoverse-512tvb is special, because it doesn't point at one specific core. It means all Neoverse cores that (a) implement SVE and (b) have a total vector bandwidth of 512 bits a cycle ๐ฆ. Unless you override it with -march, -mcpu=neoverse-512tvb generates code that can run on a Neoverse V1 core, since Neoverse V1 is the first Neoverse core with these properties ๐ฅ. Unless you override it with -mtune, it tunes code the same way -mtune=neoverse-512tvb does.
๐ง -moverride=string
This lets you override tuning decisions the back-end made in response to a -mtune= switch ๐ง. The syntax, semantics and accepted values for string are not guaranteed to stay the same across releases ๐ญ.
This option is only intended to be useful when developing GCC. Don't go poking at it in your regular builds, bestie ๐.
๐ -mverbose-cost-dump
Turns on verbose cost model dumping in the debug dump files ๐. It's there for debugging the compiler itself, so it's a compiler-dev kind of flex ๐ง .
๐ท -mpc-relative-literal-loads, -mno-pc-relative-literal-loads
Enable or disable PC-relative literal loads ๐ฆ. With this on, literal pools get accessed using a single instruction and get emitted after each function. The catch is that this caps function size at 1MB ๐. It's enabled by default for -mcmodel=tiny.
๐ -msign-return-address=scope
Picks the function scope that return address signing gets applied to ๐. The permissible values are:
noneโ turns return address signing off ๐non-leafโ turns on pointer signing for functions that aren't leaf functions ๐ฟallโ turns on pointer signing for every single function ๐
The default value is none.
Heads up, babe: this option has been deprecated in favour of -mbranch-protection ๐ฅ.
๐ -mbranch-protection=none|standard|pac-ret[+leaf+b-key]|bti
Picks which branch protection features to use โจ. Here's the lineup:
noneโ the default, turns off all types of branch protection ๐standardโ turns on all types of branch protection features. If a feature has extra tuning options,standardsets it to its standard level ๐pac-ret[+leaf]โ turns return address signing on to its standard level, signing functions that save the return address to memory (non-leaf functions will practically always do this) using the A-key ๐. The optional argumentleafextends the signing to include leaf functions ๐ฟ.b-keyโ the optional argument that signs the functions with the B-key instead of the A-key ๐๏ธbtiโ turns on the branch target identification mechanism ๐ฏ
๐ซง -mharden-sls=opts
Enables compiler hardening against straight line speculation (SLS) ๐ก๏ธ. opts is a comma-separated list of the following options:
retbrblr
On top of that, -mharden-sls=all enables all SLS hardening, and -mharden-sls=none disables all of it ๐ซ.
๐ธ -msve-vector-bits=bits
Specifies how many bits are in an SVE vector register ๐ฆ. This option only does anything when SVE is enabled, so don't expect magic without it ๐.
GCC supports two flavours of SVE code generation โจ:
- "vector-length agnostic" output, which works with any size of vector register ๐
- "vector-length specific" output, which lets GCC make assumptions about the vector length when that helps with optimization ๐ฏ
The possible values of bits are scalable, 128, 256, 512, 1024 and 2048 ๐
. Specifying scalable selects vector-length agnostic output. Right now, -msve-vector-bits=128 also generates vector-length agnostic output for big-endian targets ๐. All other values generate vector-length specific code. These behaviours may change in future releases, so no value except scalable should be relied on for code that needs to be portable across different hardware SVE vector lengths ๐ญ.
The default is -msve-vector-bits=scalable, which produces vector-length agnostic code ๐ฅฐ.
๐ฆ -march and -mcpu Feature Modifiers ๐ฆ
Feature modifiers used with -march and -mcpu can be any of the ones below, and each one also has an inverse you can write as nofeature ๐.
crcโ enables the CRC extension. This is on by default for-march=armv8.1-a๐ข.cryptoโ enables the Crypto extension. This also enables Advanced SIMD and floating-point instructions ๐.fpโ enables floating-point instructions. This is on by default for all possible values for options-marchand-mcpu๐ฅ.simdโ enables Advanced SIMD instructions. This also enables floating-point instructions. This is on by default for all possible values for options-marchand-mcpu๐.sveโ enables Scalable Vector Extension instructions. This also enables Advanced SIMD and floating-point instructions ๐.lseโ enables Large System Extension instructions. This is on by default for-march=armv8.1-a๐งฉ.rdmaโ enables Round Double Multiply Accumulate instructions. This is on by default for-march=armv8.1-aโ๏ธ.fp16โ enables the FP16 extension. This also enables floating-point instructions ๐ก๏ธ.fp16fmlโ enables the FP16 fmla extension. This also enables FP16 extensions and floating-point instructions. This is enabled by default for-march=armv8.4-a. Using this with architectures prior to Armv8.2-A is not supported ๐ .rcpcโ enables the RcPc extension. This does not change code generation from GCC, but it gets passed on to the assembler, so inline asm statements can use instructions from the RcPc extension ๐งต.dotprodโ enables the Dot Product extension. This also enables Advanced SIMD instructions ๐ฒ.aesโ enables the Armv8-aaesandpmullcrypto extension. This also enables Advanced SIMD instructions ๐๏ธ.sha2โ enables the Armv8-asha2crypto extension. This also enables Advanced SIMD instructions ๐ง.sha3โ enables thesha512andsha3crypto extension. This also enables Advanced SIMD instructions. Using this with architectures prior to Armv8.2-A is not supported ๐ซ.sm4โ enables thesm3andsm4crypto extension. This also enables Advanced SIMD instructions. Using this with architectures prior to Armv8.2-A is not supported ๐.profileโ enables the Statistical Profiling extension. This is only to enable the extension at the assembler level and does not affect code generation ๐.rngโ enables the Armv8.5-a Random Number instructions. This is only to enable the extension at the assembler level and does not affect code generation ๐ฐ.memtagโ enables the Armv8.5-a Memory Tagging Extensions. Using this with architectures prior to Armv8.5-A is not supported ๐ท๏ธ.sbโ enables the Armv8-a Speculation Barrier instruction. This is only to enable the extension at the assembler level and does not affect code generation. This is enabled by default for-march=armv8.5-a๐ง.ssbsโ enables the Armv8-a Speculative Store Bypass Safe instruction. This is only to enable the extension at the assembler level and does not affect code generation. This is enabled by default for-march=armv8.5-a๐ก๏ธ.predresโ enables the Armv8-a Execution and Data Prediction Restriction instructions. This is only to enable the extension at the assembler level and does not affect code generation. This is enabled by default for-march=armv8.5-a๐ฎ.sve2โ enables the Armv8-a Scalable Vector Extension 2. This also enables SVE instructions ๐.sve2-bitpermโ enables SVE2 bitperm instructions. This also enables SVE2 instructions ๐ช.sve2-sm4โ enables SVE2sm4instructions. This also enables SVE2 instructions ๐ฟ.sve2-aesโ enables SVE2aesinstructions. This also enables SVE2 instructions ๐๏ธ.sve2-sha3โ enables SVE2sha3instructions. This also enables SVE2 instructions ๐งช.tmeโ enables the Transactional Memory Extension ๐งพ.i8mmโ enables 8-bit Integer Matrix Multiply instructions. This also enables Advanced SIMD and floating-point instructions. This is enabled by default for-march=armv8.6-a. Using this with architectures prior to Armv8.2-A is not supported ๐ข.f32mmโ enables 32-bit Floating point Matrix Multiply instructions. This also enables SVE instructions. Using this with architectures prior to Armv8.2-A is not supported ๐งฎ.f64mmโ enables 64-bit Floating point Matrix Multiply instructions. This also enables SVE instructions. Using this with architectures prior to Armv8.2-A is not supported ๐งฎ.bf16โ enables brain half-precision floating-point instructions. This also enables Advanced SIMD and floating-point instructions. This is enabled by default for-march=armv8.6-a. Using this with architectures prior to Armv8.2-A is not supported ๐ง โจ.
Okay so crypto is literally a bundle deal ๐
crypto brings along aes, sha2, and simd, and simd brings fp with it. Going the other way, nofp drags nosimd out with it, and nosimd takes nocrypto, noaes, and nosha2 ๐ญ๐ซถ
๐ธ Adapteva Epiphany Options ๐ธ
These -m options are defined for Adapteva Epiphany โจ
-mhalf-reg-fileโ Bestie, this one says don't allocate any register in the range"r32"..."r63"๐ That lets your code run on hardware variants that don't have those registers, so it's giving compatibility.-mprefer-short-insn-regsโ Prefers registers that make short instructions possible. ngl this can bump the instruction count, so overall code size might go down or up ๐คทโโ๏ธ-mbranch-cost=numโ Sets the cost of branches to roughly num"simple"instructions. It's only a heuristic, so don't expect the same results across releases ๐ฆ-mcmoveโ Turns on the generation of conditional moves ๐-mnops=numโ Emits num NOPs before every other instruction it generates ๐ง-mno-soft-cmpsfโ For single-precision floating-point comparisons, this emits an"fsub"instruction and checks the flags. It's faster than a software comparison, BUT it can give wrong answers with NaNs, or when two different small numbers subtract to zero. The default is-msoft-cmpsf, which is slower but IEEE-compliant software comparison, so it's the safe pick ๐-mstack-offset=numโ Sets the gap between the top of the stack and the stack pointer. For example, a value of 8 means the eight bytes insp+0...sp+7can be used by leaf functions without stack allocation. Anything other than 8 or 16 is untested and probably won't work ๐ This option also changes the ABI, so building with a different stack offset than your libraries generally breaks things. It's handy for checking whether a different offset gives better code, but if you want to actually build working programs, the move is configuring the toolchain with the right--with-stack-offset=numoption.-mno-round-nearestโ Makes the scheduler assume the rounding mode is set to truncating. The default is-mround-nearest๐-mlong-callsโ Unless an attribute says otherwise, this assumes any call might be out of range of theb/blinstructions. So it loads the function address into a register before making the (otherwise direct) call. This is the default, and it's giving cautious ๐-mshort-callsโ Unless an attribute says otherwise, this assumes all direct calls are in range of theb/blinstructions, so those get used for direct calls. The default is-mlong-callsโจ-msmall16โ Assumes addresses can be loaded as 16-bit unsigned values. This doesn't apply to function addresses where-mlong-callssemantics are in effect ๐-mfp-mode=modeโ Sets the prevailing mode of the floating-point unit. This decides which FP mode gets provided and expected at function call and return time. Matching it to the mode you mostly need at function start can make your programs smaller and faster by skipping unnecessary mode switches ๐ฅ
mode can be one of the following values:
callerโ Any mode is valid at function entry, and it gets kept or restored when the function returns and when it calls other functions. This is super useful for libraries or compilation units you want to drop into programs with different FPU modes. Being able to use a single object file is worth the extra mode switching overhead, compared to a more specific choice ๐ฆtruncateโ The mode used for floating-point calculations with truncating (round toward zero) rounding. That includes floating-point to integer conversion ๐round-nearestโ The mode used for floating-point calculations with round-to-nearest-or-even rounding ๐ธintโ The mode used to do integer calculations in the FPU, like integer multiply or integer multiply-and-accumulate ๐ง
The default is -mfp-mode=caller ๐
-mno-split-lohi,-mno-postinc,-mno-postmodifyโ Code generation tweaks. These turn off, respectively, splitting of 32-bit loads, generation of post-increment addresses, and generation of post-modify addresses. The defaults aremsplit-lohi,-mpost-inc, and-mpost-modify๐-mnovect-doubleโ Changes the preferred SIMD mode to SImode. The default is-mvect-double, which uses DImode as the preferred SIMD mode โจ-max-vect-align=numโ The maximum alignment for SIMD vector mode types. num can be 4 or 8, and the default is 8. Heads up, this is an ABI change! Many library function interfaces are still unaffected, as long as they don't use SIMD vector modes in places that change the size or alignment of the relevant types ๐ซถ-msplit-vecmove-earlyโ Splits vector moves into single word moves before reload. In theory this can give better register allocation, but so far the reverse seems to be the general case ๐ญ-m1reg-regโ Picks a register to hold the constant -1, which makes loading small negative constants and certain bitmasks faster. The allowable values for reg arer43andr63, which use that register as a fixed register, andnone, which means no register is used for this purpose. The default is-m1reg-none๐
๐ฆ AMD GCN Options ๐ฆ
These options are defined specifically for the AMD GCN port ๐
-march=gpu,-mtune=gpuโ Sets the architecture type or tuning for gpu. The supported values for gpu are:fijiโ Compiles for GCN3 Fiji devices (gfx803) ๐ฅgfx900โ Compiles for GCN5 Vega 10 devices (gfx900) ๐gfx906โ Compiles for GCN5 Vega 20 devices (gfx906) โจ
-mstack-size=bytesโ Specifies how many bytes of stack space get requested for each GPU thread (wave-front).
Beware! There may be lots of threads and limited memory available, so be careful with this one ๐
The size of the stack allocation may also affect run-time performance. The default is 32KB when using OpenACC or OpenMP, and 1MB otherwise ๐ธ
๐ง ARC Options ๐ง
The following options control the architecture variant that code is being compiled for ๐
-mbarrel-shifterโ Generates instructions supported by the barrel shifter. This is the default unless-mcpu=ARC601or-mcpu=ARCEMis in effect ๐-mjli-alwaysโ Forces a function call to use thejli_sinstruction. This option is only valid for the ARCv2 architecture ๐-mcpu=cpuโ Sets the architecture type, register usage, and instruction scheduling parameters for cpu. There are also shortcut alias options for backward compatibility and convenience. The supported values for cpu are:arc600โ Compiles for ARC600. Aliases:-mA6,-mARC600๐ฆarc601โ Compiles for ARC601. Alias:-mARC601๐ฆarc700โ Compiles for ARC700. Aliases:-mA7,-mARC700. This is the default when configured with--with-cpu=arc700๐arcemโ Compiles for ARC EM ๐ธarchsโ Compiles for ARC HS ๐ธemโ Compiles for ARC EM CPU with no hardware extensions ๐em4โ Compiles for ARC EM4 CPU ๐em4_dmipsโ Compiles for ARC EM4 DMIPS CPU ๐em4_fpusโ Compiles for ARC EM4 DMIPS CPU with the single-precision floating-point extension ๐ฅem4_fpudaโ Compiles for ARC EM4 DMIPS CPU with single-precision floating-point and double assist instructions ๐ฅhsโ Compiles for ARC HS CPU with no hardware extensions except the atomic instructions ๐hs34โ Compiles for ARC HS34 CPU ๐hs38โ Compiles for ARC HS38 CPU ๐hs38_linuxโ Compiles for ARC HS38 CPU with all hardware extensions turned on ๐arc600_normโ Compiles for ARC 600 CPU with"norm"instructions enabled โจarc600_mul32x16โ Compiles for ARC 600 CPU with"norm"and 32x16-bit multiply instructions enabled โจarc600_mul64โ Compiles for ARC 600 CPU with"norm"and"mul64"-family instructions enabled โจarc601_normโ Compiles for ARC 601 CPU with"norm"instructions enabled โจarc601_mul32x16โ Compiles for ARC 601 CPU with"norm"and 32x16-bit multiply instructions enabled โจarc601_mul64โ Compiles for ARC 601 CPU with"norm"and"mul64"-family instructions enabled โจnps400โ Compiles for ARC 700 on the NPS400 chip ๐em_miniโ Compiles for an ARC EM minimalist configuration featuring a reduced register set ๐ฅบ
-mdpfp,-mdpfp-compactโ Generates double-precision FPX instructions, tuned for the compact implementation ๐-mdpfp-fastโ Generates double-precision FPX instructions, tuned for the fast implementation โญ-mno-dpfp-lrsrโ Disables"lr"and"sr"instructions from using FPX extension aux registers ๐-meaโ Generates extended arithmetic instructions. Right now only"divaw","adds","subs", and"sat16"are supported. This is only valid for-mcpu=ARC700๐ฅ-mno-mpyโ Doesn't generate"mpy"-family instructions for ARC700. This option is deprecated, so maybe skip it ๐-mmul32x16โ Generates 32x16-bit multiply and multiply-accumulate instructions ๐ฆ-mmul64โ Generates"mul64"and"mulu64"instructions. This is only valid for-mcpu=ARC600๐ฆ-mnormโ Generates"norm"instructions. This is the default if-mcpu=ARC700is in effect ๐ธ-mspfp,-mspfp-compactโ Generates single-precision FPX instructions, tuned for the compact implementation ๐-mspfp-fastโ Generates single-precision FPX instructions, tuned for the fast implementation ๐-msimdโ Enables generation of ARC SIMD instructions through target-specific builtins. This is only valid for-mcpu=ARC700๐-msoft-floatโ This option is ignored! It's only here for compatibility. Software floating-point code is emitted by default, and that default can be overridden by the FPX options:-mspfp,-mspfp-compact, or-mspfp-fastfor single precision, and-mdpfp,-mdpfp-compact, or-mdpfp-fastfor double precision ๐-mswapโ ๐ Generatesswapinstructions, bestie, so the vibe is "swap it up."-matomicโ ๐ช This turns on the locked load/store conditional extension so the atomic memory built-in functions can be implemented with it. Not available for ARC 6xx or ARC EM cores ๐ .-mdiv-remโ โ Enables thedivandreminstructions for ARCv2 cores.-mcode-densityโ ๐ง Enables code density instructions for ARC EM. This one is on by default for ARC HS.-mll64โ ๐ Enables double load/store operations for ARC HS cores.-mtp-regno=regnoโ ๐งต Specifies the thread pointer register number.-mmpy-option=multoโ โ๏ธ Compiles ARCv2 code with a multiplier design option. You can givemultoas either a string or a numeric value.wlh1is the default ๐. This is only available for ARCv2 cores. The recognized values are:0ornoneโ No multiplier available.1orwโ 16x16 multiplier, fully pipelined. Enablesmpywandmpyuw.2orwlh1โ 32x32 multiplier, fully pipelined (1 stage). Additionally enablesmpy,mpyu,mpym,mpymu, andmpy_s.3orwlh2โ 32x32 multiplier, fully pipelined (2 stages). Additionally enablesmpy,mpyu,mpym,mpymu, andmpy_s.4orwlh3โ Two 16x16 multipliers, blocking, sequential. Additionally enablesmpy,mpyu,mpym,mpymu, andmpy_s.5orwlh4โ One 16x16 multiplier, blocking, sequential. Additionally enablesmpy,mpyu,mpym,mpymu, andmpy_s.6orwlh5โ One 32x4 multiplier, blocking, sequential. Additionally enablesmpy,mpyu,mpym,mpymu, andmpy_s.7orplus_dmpyโ ARC HS SIMD support. ๐8orplus_macdโ ARC HS SIMD support. ๐9orplus_qmacwโ ARC HS SIMD support. ๐
-mfpu=fpuโ ๐งฎ Turns on support for specific floating-point hardware extensions for ARCv2 cores. The supported values forfpuare:fpusโ Enables support for single-precision floating-point hardware extensions.fpudโ Enables support for double-precision floating-point hardware extensions. The single-precision floating-point extension is also enabled. Not available for ARC EM.fpudaโ Enables support for double-precision floating-point hardware extensions using double-precision assist instructions. The single-precision floating-point extension is also enabled. Only available for ARC EM.fpuda_divโ Enables support for double-precision floating-point hardware extensions using double-precision assist instructions. The single-precision floating-point, square-root, and divide extensions are also enabled. Only available for ARC EM.fpuda_fmaโ Enables support for double-precision floating-point hardware extensions using double-precision assist instructions. The single-precision floating-point and fused multiply and add hardware extensions are also enabled. Only available for ARC EM.fpuda_allโ Enables support for double-precision floating-point hardware extensions using double-precision assist instructions. All single-precision floating-point hardware extensions are also enabled. Only available for ARC EM.fpus_divโ Enables support for single-precision floating-point, square-root and divide hardware extensions.fpud_divโ Enables support for double-precision floating-point, square-root and divide hardware extensions. This option includes optionfpus_div. Not available for ARC EM.fpus_fmaโ Enables support for single-precision floating-point and fused multiply and add hardware extensions.fpud_fmaโ Enables support for double-precision floating-point and fused multiply and add hardware extensions. This option includes optionfpus_fma. Not available for ARC EM.fpus_allโ Enables support for all single-precision floating-point hardware extensions.fpud_allโ Enables support for all single- and double-precision floating-point hardware extensions. Not available for ARC EM.
-mirq-ctrl-saved=register-range, blink, lp_countโ ๐ก๏ธ Specifies the general-purpose registers that the processor automatically saves and restores on interrupt entry and exit.register-rangeis written as two registers separated by a dash. The range always starts withr0, and the upper limit is thefpregister.blinkandlp_countare optional. This option is only valid for ARC EM and ARC HS cores.-mrgf-banked-regs=numberโ ๐ฆ Specifies how many registers get replicated in the second register bank on entry to a fast interrupt. Fast interrupts are the ones with the highest priority level,P0. They only save thePCandSTATUS32registers so they can skip memory transactions during entry and exit. Use this when you're using fast interrupts on an ARC V2 family processor. Permitted values are4,8,16, and32.-mlpc-width=widthโ ๐ข Specifies the width of thelp_countregister. Valid values forwidthare8,16,20,24,28, and32bits. The default width is fixed to 32 bits. If the width is less than 32, the compiler won't try to transform your loops into the zero-delay loop mechanism unless it's known that thelp_countregister can hold the required loop-counter value. Depending on the width you pick, the compiler and run-time library might still use the loop mechanism for various needs. This option defines the macro__ARC_LPC_WIDTH__with the value ofwidth.-mrf16โ ๐ Tells the compiler to generate code for a 16-entry register file. This option defines the__ARC_RF16__preprocessor macro.-mbranch-indexโ ๐ช Enables use ofbiorbihinstructions to implement jump tables.
The following options are passed through to the assembler, and they also define preprocessor macro symbols. ๐ง
-mdsp-packaโ Passed down to the assembler to enable the DSP Pack A extensions. Also sets the preprocessor symbol__Xdsp_packa. This option is deprecated ๐.-mdvbfโ Passed down to the assembler to enable the dual Viterbi butterfly extension. Also sets the preprocessor symbol__Xdvbf. This option is deprecated ๐.-mlockโ Passed down to the assembler to enable the locked load/store conditional extension. Also sets the preprocessor symbol__Xlock.-mmac-d16โ Passed down to the assembler. Also sets the preprocessor symbol__Xxmac_d16. This option is deprecated ๐.-mmac-24โ Passed down to the assembler. Also sets the preprocessor symbol__Xxmac_24. This option is deprecated ๐.-mrtscโ Passed down to the assembler to enable the 64-bit time-stamp counter extension instruction. Also sets the preprocessor symbol__Xrtsc. This option is deprecated ๐.-mswapeโ Passed down to the assembler to enable the swap byte ordering extension instruction. Also sets the preprocessor symbol__Xswape.-mtelephonyโ Passed down to the assembler to enable dual- and single-operand instructions for telephony. Also sets the preprocessor symbol__Xtelephony. This option is deprecated ๐.-mxyโ Passed down to the assembler to enable the XY memory extension. Also sets the preprocessor symbol__Xxy.
The following options control how the assembly code gets annotated ๐:
-misizeโ Annotates assembler instructions with estimated addresses.-mannotate-alignโ Explains what alignment considerations led to the decision to make an instruction short or long.
The following options are passed through to the linker ๐:
-marclinuxโ Passed through to the linker to specify use of thearclinuxemulation. This is enabled by default in tool chains built forarc-linux-uclibcandarceb-linux-uclibctargets when profiling is not requested.-marclinux_profโ Passed through to the linker to specify use of thearclinux_profemulation. This is enabled by default in tool chains built forarc-linux-uclibcandarceb-linux-uclibctargets when profiling is requested.
The following options control the semantics of the generated code ๐ง :
-mlong-callsโ Generates calls as register indirect calls, which gives access to the full 32-bit address range.-mmedium-callsโ Doesn't use less than a 25-bit addressing range for calls, which is the offset available for an unconditional branch-and-link instruction. Conditional execution of function calls is suppressed so the 25-bit range can be used, instead of the 21-bit range you'd get with conditional branch-and-link. This is the default for tool chains built forarc-linux-uclibcandarceb-linux-uclibctargets.-G numโ Puts definitions of externally-visible data in a small data section if that data is no bigger thannumbytes. The default value ofnumis4for any ARC configuration, or8when double load/store operations are available.-mno-sdataโ Doesn't generatesdatareferences. This is the default for tool chains built forarc-linux-uclibcandarceb-linux-uclibctargets.-mvolatile-cacheโ Uses ordinarily cached memory accesses for volatile references. This is the default ๐.-mno-volatile-cacheโ Enables cache bypass for volatile references.
The following options fine-tune code generation โจ:
-malign-callโ Does alignment optimizations for call instructions.-mauto-modify-regโ Enables the use of pre/post modify with register displacement.-mbbit-peepholeโ Enablesbbitpeephole2.-mno-brccโ This option disables a target-specific pass inarc_reorgthat generates compare-and-branch (brcc) instructions. It has no effect on the generation of these instructions when they're driven by the combiner pass.
-mcase-vector-pcrel okay so this one turns on PC-relative switch case tables ๐ฆ so the switch case tables can get shortened โจ this is the default for -Os ๐
-mcase-vector-pcrelโ switch case tables go PC-relative, which lets the compiler shrink them ๐ธ-mcompact-casesiโ turns on the compactcasesipattern ๐ default for-Os, and it's only available for ARCv1 cores ๐ this option is deprecated ๐ญ-mno-cond-execโ switches off the ARCompact-only pass that generates conditional execution instructions ๐
okay this one is kinda a lot, bestie ๐ซถ the target-independent conditional execution pass is often lacking on ARC because of delay slot scheduling and the interplay between operand numbers, literal sizes, instruction lengths, and conditional execution support ๐ so the ARC port keeps a special pass around that hunts for extra conditional execution chances after register allocation, branch shortening, and delay slot scheduling are done โจ it generally (not always!) makes performance and code size better, but it costs extra compile time, which is why you can switch it off ๐
โ ๏ธ if call instructions blow past their allowed offset range because they got conditionalized, try -mmedium-calls instead ๐ญ
-mearly-cbranchsiโ enables pre-reload use of thecbranchsipattern ๐ง-mexpand-adddiโ expandsadddi3andsubdi3at RTL generation time intoadd.f,adcetc. ๐ this option is deprecated ๐-mindexed-loadsโ enables indexed loads ๐ heads up, this can be problematic because some optimizers then assume indexed stores exist, and they don't ๐-mlraโ enables Local Register Allocation ๐ฅ still experimental for ARC, so by default the compiler uses standard reload (that's-mno-lra) ๐ซ-mlra-priority-noneโ doesn't indicate any priority for target registers ๐ธ-mlra-priority-compactโ indicates target register priority forr0..r3/r12..r15๐-mlra-priority-noncompactโ reduces target register priority forr0..r3/r12..r15๐ฆ-mmillicodeโ when optimizing for size (-Os), prologues and epilogues that have to save or restore a ton of registers often get shortened by calling a special function in libgcc, and that's called a millicode call ๐ these calls can cause performance issues, and/or linking issues when you link in a nonstandard way, so this option lets you turn millicode call generation on or off ๐-mcode-density-frameโ lets the compiler emitenterandleaveinstructions โจ these are only valid for CPUs with the code-density feature ๐-mmixed-codeโ tweaks register allocation to help 16-bit instruction generation ๐ง it usually makes the average instruction size smaller while the instruction count goes up ๐-mq-classโ deprecated ๐ญ enablesqinstruction alternatives, and it's the default for-Os๐-mRcqโ enablesRcqconstraint handling ๐ most short code generation depends on this, and it's the default โญ-mRcwโ enablesRcwconstraint handling ๐ซถ most ccfsm condexec mostly depends on this, and it's the default ๐-msize-level=levelโ fine-tunes size optimization around instruction lengths and alignment ๐ฅ the values forlevelare:0โ no size optimization. deprecated, and it's treated like1๐1โ short instructions get used opportunistically โจ2โ on top of that, alignment of loops and of code after barriers gets dropped ๐ฆ3โ on top of that, optional data alignment gets dropped, and the optionOsis enabled ๐
it defaults to 3 when -Os is in effect ๐
otherwise, leaving it unset works the same as level 1 ๐ธ
-mtune=cpuโ sets instruction scheduling parameters forcpu, overriding anything implied by-mcpu=๐
supported values for cpu are:
ARC600โ tunes for the ARC600 CPU ๐งARC601โ tunes for the ARC601 CPU ๐ฆARC700โ tunes for the ARC700 CPU with the standard multiplier block ๐ARC700-xmacโ tunes for the ARC700 CPU with the XMAC block ๐ARC725Dโ tunes for the ARC725D CPU โจARC750Dโ tunes for the ARC750D CPU ๐
-mmultcost=numโ the cost to assume for a multiply instruction, with4being equal to a normal instruction ๐-munalign-prob-threshold=probabilityโ sets the probability threshold for unaligning branches ๐ซถ when tuning for ARC700 and optimizing for speed, branches without a filled delay slot are preferably emitted unaligned and long, unless profiling says the probability of the branch being taken is below probability ๐ the default is(REG_BR_PROB_BASE/2), i.e.5000๐ฅ
the following options are kept around for backward compatibility, but they're now deprecated and will be removed in a future release ๐ญ๐ฅ
-margonautโ obsolete FPX ๐-mbig-endian,-EBโ compile code for big-endian targets ๐ using these is now deprecated ๐ญ big-endian code is supported by configuring GCC to build thearceb-elf32andarceb-linux-uclibctargets, where big endian is the default ๐ฆ-mlittle-endian,-ELโ compile code for little-endian targets ๐ using these is now deprecated ๐ญ little-endian code is supported by configuring GCC to build thearc-elf32andarc-linux-uclibctargets, where little endian is the default ๐ง-mbarrel_shifterโ replaced by-mbarrel-shifter๐-mdpfp_compactโ replaced by-mdpfp-compact๐ธ-mdpfp_fastโ replaced by-mdpfp-fastโจ-mdsp_packaโ replaced by-mdsp-packa๐ซถ-mEAโ replaced by-mea๐-mmac_24โ replaced by-mmac-24๐-mmac_d16โ replaced by-mmac-d16๐ฅ-mspfp_compactโ replaced by-mspfp-compact๐ฆ-mspfp_fastโ replaced by-mspfp-fast๐-mtune=cpuโ the valuesarc600,arc601,arc700andarc700-xmacforcpuare replaced byARC600,ARC601,ARC700andARC700-xmacrespectively ๐-multcost=numโ replaced by-mmultcost๐
โจ ARM Options โจ
these -m options are defined for the ARM port ๐ธ
-mabi=nameโ generates code for the specified ABI ๐ permissible values are:apcs-gnu,atpcs,aapcs,aapcs-linuxandiwmmxt๐-mapcs-frameโ generates a stack frame that follows the ARM Procedure Call Standard for all functions, even if it isn't strictly needed for the code to run correctly ๐ฆ combining it with-fomit-frame-pointermeans stack frames aren't generated for leaf functions ๐ง the default is-mno-apcs-frame๐ this option is deprecated ๐ญ-mapcsโ a synonym for-mapcs-frame, and it's deprecated ๐-mthumb-interworkโ generates code that supports calling between the ARM and Thumb instruction sets ๐ without this, on pre-v5 architectures, the two instruction sets can't be reliably used inside one program ๐ the default is-mno-thumb-interwork, since the code gets slightly bigger when-mthumb-interworkis on ๐ in AAPCS configurations this option is meaningless ๐-mno-sched-prologโ stops the reordering of instructions in the function prologue, and stops merging those instructions with the ones in the function's body ๐ซถ that means every function starts with a recognizable set of instructions (or one of a small set of prologues), so you can use that to find where functions start in an executable chunk of code ๐ฅ the default is-msched-prologโจ-mfloat-abi=nameโ picks which floating-point ABI to use ๐ permissible values are:soft,softfpandhard๐softโ GCC generates output with library calls for floating-point operations ๐ธsoftfpโ allows hardware floating-point instructions, but still uses the soft-float calling conventions ๐ฆhardโ allows floating-point instructions and uses FPU-specific calling conventions ๐
the default depends on the specific target configuration ๐ง the hard-float and soft-float ABIs are NOT link-compatible ๐ญ you have to compile your whole program with the same ABI and link with a compatible set of libraries ๐
-mgeneral-regs-onlyโ generates code that only uses the general-purpose registers ๐ this stops the compiler from using floating-point and Advanced SIMD registers, but it won't put any restrictions on the assembler ๐-mlittle-endianโ generates code for a processor running in little-endian mode ๐ this is the default for all standard configurations ๐-mbig-endianโ generates code for a processor running in big-endian mode ๐ซถ the default is to compile for a little-endian processor ๐ฅ-mbe8,-mbe32โ when linking a big-endian image, selects between the BE8 and BE32 formats ๐ it has no effect on little-endian images and gets ignored there โจ the default depends on the selected target architecture ๐ฆ for ARMv6 and later the default is BE8, and for older architectures the default is BE32 ๐ BE32 format has been deprecated by ARM ๐ญ-march=name[+extension...]โ specifies the name of the target ARM architecture ๐ธ GCC uses this name to figure out what kinds of instructions it can emit when generating assembly code ๐ง this option can be used together with, or instead of,-mcpu=๐
permissible names are: armv4t, armv5t, armv5te, armv6, armv6j, armv6k, armv6kz, armv6t2, armv6z, armv6zk, armv7, armv7-a, armv7ve, armv8-a, armv8.1-a, armv8.2-a, armv8.3-a, armv8.4-a, armv8.5-a, armv8.6-a, armv7-r, armv8-r, armv6-m, armv6s-m, armv7-m, armv7e-m, armv8-m.base, armv8-m.main, armv8.1-m.main, iwmmxt and iwmmxt2 ๐ซถ
also, these architectures don't support the Thumb execution state, so they're recognized but support is deprecated: armv4 ๐
lots of the architectures support extensions ๐ you can add them by appending +extension to the architecture name ๐ extension options get processed in order and capabilities pile up ๐ an extension also turns on any base extensions it depends on, like how +crypto will always turn on +simd ๐ฅ the exception to the stacking rule is extensions prefixed with +no..., which switch off the specified option and any other extensions that depend on it ๐ periodt ๐
โจ
For example, -march=armv7-a+simd+nofp+vfpv4 is the same as -march=armv7-a+vfpv4 ๐
because the +nofp that comes after +simd wipes out +simd completely ๐ lowkey a trap if you're not paying attention ๐
Most extension names are generic, but what they actually do depends on which architecture they're attached to ๐ฆ For example, +simd works on both armv7-a and armv8-a. On armv7-a it gives you the original ARMv7-A Advanced SIMD (Neon) extensions, and on armv8-a it gives you the ARMv8-A version โจ
Here's the tea โ The table below lists the supported extensions for each architecture. Any architecture that isn't mentioned doesn't support any extensions at all ๐ฅฒ
armv5te, armv6, armv6j, armv6k, armv6kz, armv6t2, armv6z, armv6zk ๐ธ
+fpโ The VFPv2 floating-point instructions. You can also use+vfpv2as an alias for this one ๐+nofpโ Turns off the floating-point instructions ๐ซ
armv7 ๐
The common subset of the ARMv7-A, ARMv7-R and ARMv7-M architectures, so it's the baseline everyone shares ๐ซถ
+fpโ The VFPv3 floating-point instructions, with 16 double-precision registers. You can use+vfpv3-d16as an alias for this one. Heads up: floating-point isn't supported by the base ARMv7-M architecture, but it is compatible with both ARMv7-A and ARMv7-R ๐+nofpโ Turns off the floating-point instructions ๐ซ
armv7-a ๐
+mpโ The multiprocessing extension ๐ง+secโ The security extension ๐+fpโ The VFPv3 floating-point instructions, with 16 double-precision registers.+vfpv3-d16works as an alias here too โจ+simdโ The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions.+neonand+neon-vfpv3can both be used as aliases for this one ๐ฅ+vfpv3โ The VFPv3 floating-point instructions, with 32 double-precision registers ๐+vfpv3-d16-fp16โ The VFPv3 floating-point instructions, with 16 double-precision registers plus the half-precision floating-point conversion operations ๐ง+vfpv3-fp16โ The VFPv3 floating-point instructions, with 32 double-precision registers plus the half-precision floating-point conversion operations ๐ง+vfpv4-d16โ The VFPv4 floating-point instructions, with 16 double-precision registers ๐ฆ+vfpv4โ The VFPv4 floating-point instructions, with 32 double-precision registers ๐ฆ+neon-fp16โ The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions, plus the half-precision floating-point conversion operations ๐+neon-vfpv4โ The Advanced SIMD (Neon) v2 and the VFPv4 floating-point instructions ๐+nosimdโ Turns off the Advanced SIMD instructions. Floating point stays on though, so it doesn't touch that part ๐+nofpโ Turns off the floating-point and Advanced SIMD instructions ๐ซ
armv7ve ๐
The extended version of the ARMv7-A architecture, with support for virtualization ๐ธ
+fpโ The VFPv4 floating-point instructions, with 16 double-precision registers.+vfpv4-d16works as an alias here โจ+simdโ The Advanced SIMD (Neon) v2 and the VFPv4 floating-point instructions.+neon-vfpv4can be used as an alias for this one ๐ฅ+vfpv3-d16โ The VFPv3 floating-point instructions, with 16 double-precision registers ๐+vfpv3โ The VFPv3 floating-point instructions, with 32 double-precision registers ๐+vfpv3-d16-fp16โ The VFPv3 floating-point instructions, with 16 double-precision registers plus the half-precision floating-point conversion operations ๐ง+vfpv3-fp16โ The VFPv3 floating-point instructions, with 32 double-precision registers plus the half-precision floating-point conversion operations ๐ง+vfpv4-d16โ The VFPv4 floating-point instructions, with 16 double-precision registers ๐ฆ+vfpv4โ The VFPv4 floating-point instructions, with 32 double-precision registers ๐ฆ+neonโ The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions.+neon-vfpv3can be used as an alias for this one ๐+neon-fp16โ The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions, plus the half-precision floating-point conversion operations ๐+nosimdโ Turns off the Advanced SIMD instructions. Floating point stays on ๐+nofpโ Turns off the floating-point and Advanced SIMD instructions ๐ซ
armv8-a ๐
+crcโ The Cyclic Redundancy Check (CRC) instructions ๐งฎ+simdโ The ARMv8-A Advanced SIMD and floating-point instructions ๐ฅ+cryptoโ The cryptographic instructions ๐+nocryptoโ Turns off the cryptographic instructions ๐ซ+nofpโ Turns off the floating-point, Advanced SIMD and cryptographic instructions ๐ซ+sbโ The Speculation Barrier instruction ๐ก๏ธ+predresโ The Execution and Data Prediction Restriction instructions ๐ก๏ธ
armv8.1-a ๐ฆ
+simdโ The ARMv8.1-A Advanced SIMD and floating-point instructions ๐ฅ+cryptoโ The cryptographic instructions. This also turns on the Advanced SIMD and floating-point instructions ๐+nocryptoโ Turns off the cryptographic instructions ๐ซ+nofpโ Turns off the floating-point, Advanced SIMD and cryptographic instructions ๐ซ+sbโ The Speculation Barrier instruction ๐ก๏ธ+predresโ The Execution and Data Prediction Restriction instructions ๐ก๏ธ
armv8.2-a, armv8.3-a ๐
+fp16โ The half-precision floating-point data processing instructions. This also turns on the Advanced SIMD and floating-point instructions ๐+fp16fmlโ The half-precision floating-point fmla extension. This also turns on the half-precision floating-point extension, plus the Advanced SIMD and floating-point instructions ๐+simdโ The ARMv8.1-A Advanced SIMD and floating-point instructions ๐ฅ+cryptoโ The cryptographic instructions. This also turns on the Advanced SIMD and floating-point instructions ๐+dotprodโ Enables the Dot Product extension. This also turns on Advanced SIMD instructions โจ+nocryptoโ Turns off the cryptographic extension ๐ซ+nofpโ Turns off the floating-point, Advanced SIMD and cryptographic instructions ๐ซ+sbโ The Speculation Barrier instruction ๐ก๏ธ+predresโ The Execution and Data Prediction Restriction instructions ๐ก๏ธ+i8mmโ The 8-bit Integer Matrix Multiply instructions. This also turns on Advanced SIMD and floating-point instructions ๐+bf16โ The Brain half-precision floating-point instructions. This also turns on Advanced SIMD and floating-point instructions ๐ง
armv8.4-a ๐ธ
+fp16โ The half-precision floating-point data processing instructions. This also turns on the Advanced SIMD and floating-point instructions, plus the Dot Product extension and the half-precision floating-point fmla extension ๐+simdโ The ARMv8.3-A Advanced SIMD and floating-point instructions, plus the Dot Product extension ๐ฅ+cryptoโ The cryptographic instructions. This also turns on the Advanced SIMD and floating-point instructions, plus the Dot Product extension ๐+nocryptoโ Turns off the cryptographic extension ๐ซ+nofpโ Turns off the floating-point, Advanced SIMD and cryptographic instructions ๐ซ+sbโ The Speculation Barrier instruction ๐ก๏ธ+predresโ The Execution and Data Prediction Restriction instructions ๐ก๏ธ+i8mmโ The 8-bit Integer Matrix Multiply instructions. This also turns on Advanced SIMD and floating-point instructions ๐+bf16โ The Brain half-precision floating-point instructions. This also turns on Advanced SIMD and floating-point instructions ๐ง
armv8.5-a ๐ง
+fp16โ The half-precision floating-point data processing instructions. This also turns on the Advanced SIMD and floating-point instructions, plus the Dot Product extension and the half-precision floating-point fmla extension ๐+simdโ The ARMv8.3-A Advanced SIMD and floating-point instructions, plus the Dot Product extension ๐ฅ+cryptoโ The cryptographic instructions. This also turns on the Advanced SIMD and floating-point instructions, plus the Dot Product extension ๐+nocryptoโ Turns off the cryptographic extension ๐ซ+nofpโ Turns off the floating-point, Advanced SIMD and cryptographic instructions ๐ซ+i8mmโ The 8-bit Integer Matrix Multiply instructions. This also turns on Advanced SIMD and floating-point instructions ๐+bf16โ The Brain half-precision floating-point instructions. This also turns on Advanced SIMD and floating-point instructions ๐งarmv8.6-a๐+fp16โ the half-precision floating-point data processing instructions ๐ซถ This also turns on the Advanced SIMD and floating-point instructions, plus the Dot Product extension and the half-precisionfmlaextension.+simdโ the ARMv8.3-A Advanced SIMD and floating-point instructions, along with the Dot Product extension โจ+cryptoโ the cryptographic instructions ๐ This also enables the Advanced SIMD and floating-point instructions and the Dot Product extension.+nocryptoโ turns off the cryptographic extension ๐ โโ๏ธ+nofpโ turns off the floating-point, Advanced SIMD and cryptographic instructions all at once ๐+i8mmโ the 8-bit Integer Matrix Multiply instructions ๐งฎ This also enables Advanced SIMD and floating-point instructions.+bf16โ the Brain half-precision floating-point instructions ๐ง This also enables Advanced SIMD and floating-point instructions.
armv7-r๐ธ+fp.spโ the single-precision VFPv3 floating-point instructions ๐ฆ+vfpv3xdworks as an alias for this one.+fpโ the VFPv3 floating-point instructions with 16 double-precision registers ๐+vfpv3-d16works as an alias for this one.+vfpv3xd-d16-fp16โ the single-precision VFPv3 floating-point instructions with 16 double-precision registers, plus the half-precision floating-point conversion operations โจ+vfpv3-d16-fp16โ the VFPv3 floating-point instructions with 16 double-precision registers, plus the half-precision floating-point conversion operations ๐+nofpโ disables the floating-point extension ๐+idivโ the ARM-state integer division instructions โ+noidivโ disables the ARM-state integer division extension ๐ซ
armv7e-m๐+fpโ the single-precision VFPv4 floating-point instructions ๐ฅ+fpv5โ the single-precision FPv5 floating-point instructions โญ+fp.dpโ the single- and double-precision FPv5 floating-point instructions ๐+nofpโ disables the floating-point extensions ๐
armv8.1-m.main๐ง+dspโ the DSP instructions ๐ถ+mveโ the M-Profile Vector Extension (MVE) integer instructions ๐+mve.fpโ the M-Profile Vector Extension (MVE) integer and single precision floating-point instructions ๐ฅ+fpโ the single-precision floating-point instructions โญ+fp.dpโ the single- and double-precision floating-point instructions ๐+nofpโ disables the floating-point extension ๐+cdecp0, +cdecp1, ... , +cdecp7โ enables the Custom Datapath Extension (CDE) on selected coprocessors, based on the numbers you pass in the range 0 to 7 ๐ ๏ธ
armv8-m.main๐ฆ+dspโ the DSP instructions ๐ถ+nodspโ disables the DSP extension ๐ โโ๏ธ+fpโ the single-precision floating-point instructions โญ+fp.dpโ the single- and double-precision floating-point instructions ๐+nofpโ disables the floating-point extension ๐+cdecp0, +cdecp1, ... , +cdecp7โ enables the Custom Datapath Extension (CDE) on selected coprocessors, based on the numbers you pass in the range 0 to 7 ๐ ๏ธ
armv8-r๐ท+crcโ the Cyclic Redundancy Check (CRC) instructions ๐+fp.spโ the single-precision FPv5 floating-point instructions ๐ฆ+simdโ the ARMv8-A Advanced SIMD and floating-point instructions โจ+cryptoโ the cryptographic instructions ๐+nocryptoโ disables the cryptographic instructions ๐ โโ๏ธ+nofpโ disables the floating-point, Advanced SIMD and cryptographic instructions ๐
-march=native tells the compiler to auto-detect the architecture of the build computer ๐ต๏ธโโ๏ธ Heads up: right now this only works on GNU/Linux, and not every architecture gets recognized. If the auto-detect doesn't work out, the option has no effect ๐ฅฒ
-mtune=name
This one tells GCC which target ARM processor to tune the performance of your code for ๐ฏ On some ARM implementations you can get better performance by using it. The permissible names are:
arm7tdmi, arm7tdmi-s, arm710t,
arm720t, arm740t, strongarm, strongarm110, strongarm1100,
0strongarm1110, arm8, arm810, arm9, arm9e, arm920, arm920t, arm922t,
arm946e-s, arm966e-s, arm968e-s, arm926ej-s, arm940t, arm9tdmi,
arm10tdmi, arm1020t, arm1026ej-s, arm10e, arm1020e, arm1022e,
arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1156t2-s,
arm1156t2f-s, arm1176jz-s, arm1176jzf-s, generic-armv7-a, cortex-a5,
cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17,
cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57,
cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae,
cortex-a77, ares, cortex-r4, cortex-r4f, cortex-r5, cortex-r7,
cortex-r8, cortex-r52, cortex-m0, cortex-m0plus, cortex-m1,
cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33,
cortex-m35p, cortex-m55, cortex-m1.small-multiply,
cortex-m0.small-multiply, cortex-m0plus.small-multiply, exynos-m1,
marvell-pj4, neoverse-n1, neoverse-n2, neoverse-v1, xscale, iwmmxt,
iwmmxt2, ep9312, fa526, fa626, fa606te, fa626te, fmp626, fa726te,
xgene1.
Oh, and it can also tune for a big.LITTLE system ๐งฉ The names for those are:
cortex-a15.cortex-a7, cortex-a17.cortex-a7,
cortex-a57.cortex-a53, cortex-a72.cortex-a53, cortex-a72.cortex-a35,
cortex-a73.cortex-a53, cortex-a75.cortex-a55, cortex-a76.cortex-a55.
-mtune=generic-arch tells GCC to tune for a blend of processors within the architecture arch ๐ The goal is code that runs well on the most popular processors right now, balancing optimizations that help some CPUs in the range while dodging the performance pitfalls of others. The effects of this option may change in future GCC versions as CPU models come and go ๐
-mtune takes the same extension options as -mcpu, but the extension options don't affect how the generated code gets tuned ๐
-mtune=native tells the compiler to auto-detect the CPU of the build computer ๐ Same catch as before: it's only supported on GNU/Linux, not every architecture is recognized, and if the auto-detect fails the option has no effect ๐
-mcpu=name[+extension...]
This specifies the name of the target ARM processor ๐ GCC uses that name to figure out the target ARM architecture (like -march would) and the ARM processor type to tune performance for (like -mtune would). If you use this option alongside -march or -mtune, those win for their part of the job ๐
Lots of the supported CPUs have optional architectural extensions, and those are usually enabled by default โ
If there are implementations that lack the extension, you can use the extension syntax to switch off the ones that are missing. For floating-point and Advanced SIMD (Neon) instructions, you also have to think about -mfloat-abi and -mfpu: floating-point and Advanced SIMD instructions only get used if -mfloat-abi isn't set to soft, and any -mfpu setting other than auto will override the available floating-point and SIMD extension instructions ๐ง
For example, cortex-a9 shows up in three main configurations: integer only, with just a floating-point unit, or with floating-point and Advanced SIMD ๐ง All the instructions are enabled by default, but you can use +nosimd and +nofp to disable just the SIMD instructions, or both the SIMD and floating-point instructions, respectively ๐
The permissible names for this option are the same as the ones for -mtune ๐
The following extension options are common to the listed CPUs ๐
+nodspโ disables the DSP instructions oncortex-m33andcortex-m35p๐ โโ๏ธ+nofpโ disables the floating-point instructions onarm9e,arm946e-s,arm966e-s,arm968e-s,arm10e,arm1020e,arm1022e,arm926ej-s,arm1026ej-s,cortex-r5,cortex-r7,cortex-r8,cortex-m4,cortex-m7,cortex-m33andcortex-m35p๐ It also disables the floating-point and SIMD instructions ongeneric-armv7-a,cortex-a5,cortex-a7,cortex-a8,cortex-a9,cortex-a12,cortex-a15,cortex-a17,cortex-a15.cortex-a7,cortex-a17.cortex-a7,cortex-a32,cortex-a35,cortex-a53andcortex-a55๐ญ+nofp.dpโ disables the double-precision part of the floating-point instructions oncortex-r5,cortex-r7,cortex-r8,cortex-r52andcortex-m7๐ฅบ+nosimdโ disables the SIMD instructions (but not the floating-point ones) ongeneric-armv7-a,cortex-a5,cortex-a7andcortex-a9๐ซ+cryptoโ enables the cryptographic instructions oncortex-a32,cortex-a35,cortex-a53,cortex-a55,cortex-a57,cortex-a72,cortex-a73,cortex-a75,exynos-m1,xgene1,cortex-a57.cortex-a53,cortex-a72.cortex-a53,cortex-a73.cortex-a35,cortex-a73.cortex-a53andcortex-a75.cortex-a55๐
On top of that, the generic-armv7-a pseudo target defaults to VFPv3 with 16 double-precision registers โจ It supports these extension options: mp, sec, vfpv3-d16, vfpv3, vfpv3-d16-fp16, vfpv3-fp16, vfpv4-d16, vfpv4, neon, neon-vfpv3, neon-fp16 and neon-vfpv4. They mean the same thing as the extensions to -march=armv7-a ๐
-mcpu=generic-arch is also allowed, and it's equivalent to -march=arch -mtune=generic-arch. Check out -mtune for more info ๐ฆ
okay so -mcpu=native is giving auto-pilot ๐
It tells the compiler to auto-detect the CPU of the build computer ๐ฅ๏ธ ngl, this only works on GNU/Linux ๐ง for now, and not every architecture gets recognized ๐ฅฒ. If the auto-detect doesn't land, the option just has no effect. no drama ๐ซถ
-mfpu=nameโ bestie, this is where you tell GCC what floating-point hardware (or hardware emulation) the target actually has ๐งฎโจ Your options areauto,vfpv2,vfpv3,vfpv3-fp16,vfpv3-d16,vfpv3-d16-fp16,vfpv3xd,vfpv3xd-fp16,neon-vfpv3,neon-fp16,vfpv4,vfpv4-d16,fpv4-sp-d16,neon-vfpv4,fpv5-d16,fpv5-sp-d16,fp-armv8,neon-fp-armv8andcrypto-neon-fp-armv8. Note thatneonis an alias forneon-vfpv3andvfpis an alias forvfpv2๐
auto is the default and it's so special ๐ฆ It makes the compiler pick the floating-point and Advanced SIMD instructions based on your -mcpu and -march settings.
If your floating-point hardware has the NEON extension (like -mfpu=neon), heads up: floating-point operations won't be generated by GCC's auto-vectorization pass unless you also specify -funsafe-math-optimizations ๐ The reason is that NEON hardware doesn't fully implement the IEEE 754 standard for floating-point arithmetic (in particular, denormal values get treated as zero), so using NEON instructions may lead to a loss of precision ๐ญ
You can also set the fpu name at function level by using the target("fpu=") function attributes or pragmas ๐ธ
-mfp16-format=nameโ this sets the format of the__fp16half-precision floating-point type ๐ Your names arenone,ieee, andalternative. The default isnone, which means the__fp16type isn't defined at all ๐-mstructure-size-boundary=nโ all structures and unions get rounded up to a multiple of the number of bits you set here ๐ Permissible values are8,32and64. The default varies between toolchains; for the COFF targeted toolchain it's8. A value of64is only allowed if the underlying ABI supports it. Going bigger can give you faster, more efficient code, but it can also increase the size of your program ๐ Different values are potentially incompatible, too. Code compiled with one value can't necessarily be expected to work with code or libraries compiled with another if they exchange info using structures or unions ๐
Deprecated โ this option is deprecated ๐ฅ
-mabort-on-noreturnโ generates a call to the functionabortat the end of anoreturnfunction ๐งจ It gets executed if the function tries to return.-mlong-calls,-mno-long-callsโ tells the compiler to perform function calls by first loading the address of the function into a register, and then performing a subroutine call on that register ๐ You need this switch if the target function lies outside the 64-megabyte addressing range of the offset-based version of the subroutine call instruction. Even with this switch enabled, not all function calls become long calls ๐ โโ๏ธ The heuristic is that static functions, functions that have theshort_callattribute, functions inside the scope of a#pragma no_long_callsdirective, and functions whose definitions have already been compiled within the current compilation unit are not turned into long calls. The exceptions are weak function definitions, functions with thelong_callattribute or thesectionattribute, and functions within the scope of a#pragma long_callsdirective, which are always turned into long calls ๐ This feature is not enabled by default.-mno-long-callsrestores the default behavior, as does placing the function calls within the scope of a#pragma long_calls_offdirective ๐งน Also, note these switches have no effect on how the compiler generates code to handle function calls via function pointers ๐ซ-msingle-pic-baseโ treats the register used for PIC addressing as read-only, instead of loading it in the prologue for each function ๐ The runtime system is responsible for initializing this register with an appropriate value before execution begins.-mpic-register=regโ specifies the register to be used for PIC addressing ๐ฏ For the standard PIC base case, the default is any suitable register determined by the compiler. For the single PIC base case, the default isR9if the target is EABI based or stack-checking is enabled, otherwise the default isR10.-mpic-data-is-text-relativeโ assumes the displacement between the text and data segments is fixed at static link time ๐งท This permits using PC-relative addressing operations to access data known to be in the data segment. For non-VxWorks RTP targets, this option is enabled by default. When it's disabled on such targets, it will enable-msingle-pic-baseby default.-mpoke-function-nameโ writes the name of each function into the text section, directly preceding the function prologue โ๏ธ The generated code is similar to this:
t0 .ascii "arm_poke_function_name", 0 .align t1 .word 0xff000000 + (t1 - t0) arm_poke_function_name mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4
When performing a stack backtrace, code can inspect the value of pc stored at fp + 0. If the trace function then looks at location pc - 12 and the top 8 bits are set, then we know that there is a function name embedded immediately preceding this location, and it has length ((pc[-3]) & 0xff000000) ๐ iykyk ๐ง
-mthumb,-marmโ selects between generating code that executes in ARM and Thumb states ๐ The default for most configurations is ARM state, but you can change it by configuring GCC with the--with-mode=stateconfigure option. You can also override the ARM and Thumb mode for each function using thetarget("thumb")andtarget("arm")function attributes or pragmas โจ-mflip-thumbโ switches ARM/Thumb modes on alternating functions ๐ This one is for regression testing of mixed Thumb/ARM code generation, and it is not intended for ordinary use when compiling code ๐ซ-mtpcs-frameโ generates a stack frame that is compliant with the Thumb Procedure Call Standard for all non-leaf functions. (A leaf function is one that does not call any other functions ๐) The default is-mno-tpcs-frame.-mtpcs-leaf-frameโ generates a stack frame that is compliant with the Thumb Procedure Call Standard for all leaf functions. (A leaf function is one that does not call any other functions.) The default is-mno-apcs-leaf-frame.-mcallee-super-interworkingโ gives all externally visible functions in the file being compiled an ARM instruction set header, which switches to Thumb mode before executing the rest of the function ๐ This allows these functions to be called from non-interworking code. This option is not valid in AAPCS configurations, because interworking is enabled by default.-mcaller-super-interworkingโ allows calls via function pointers (including virtual functions) to execute correctly, regardless of whether the target code has been compiled for interworking or not ๐ค There is a small overhead in the cost of executing a function pointer if this option is enabled. This option is not valid in AAPCS configurations, because interworking is enabled by default.-mtp=nameโ specifies the access model for the thread local storage pointer ๐งต The valid models aresoft, which generates calls to__aeabi_read_tp;cp15, which fetches the thread pointer fromcp15directly (supported in thearm6karchitecture); andauto, which uses the best available method for the selected processor. The default setting isauto๐-mtls-dialect=dialectโ specifies the dialect to use for accessing thread local storage ๐ฃ๏ธ Two dialects are supported:gnuandgnu2. Thegnudialect selects the original GNU scheme for supporting local and global dynamic TLS models. Thegnu2dialect selects the GNU descriptor scheme, which provides better performance for shared libraries ๐ The GNU descriptor scheme is compatible with the original scheme, but does require new assembler, linker and library support. Initial and local exec TLS models are unaffected by this option and always use the original scheme.-mword-relocationsโ only generates absolute relocations on word-sized values (i.e.R_ARM_ABS32) ๐งฑ This is enabled by default on targets (uClinux, SymbianOS) where the runtime loader imposes this restriction, and when-fpicor-fPICis specified. This option conflicts with-mslow-flash-data.-mfix-cortex-m3-ldrdโ some Cortex-M3 cores can cause data corruption whenldrdinstructions with overlapping destination and base registers are used ๐ฑ This option avoids generating these instructions. It is enabled by default when-mcpu=cortex-m3is specified ๐ก๏ธ-munaligned-access,-mno-unaligned-accessโ enables (or disables) reading and writing of 16- and 32-bit values from addresses that are not 16- or 32-bit aligned ๐ By default, unaligned access is disabled for all pre-ARMv6, all ARMv6-M and for ARMv8-M Baseline architectures, and enabled for all other architectures. If unaligned access is not enabled, then words in packed data structures are accessed a byte at a time ๐ข The ARM attributeTag_CPU_unaligned_accessis set in the generated object file to either true or false, depending upon the setting of this option. If unaligned access is enabled, then the preprocessor symbol__ARM_FEATURE_UNALIGNEDis also defined ๐-mneon-for-64bitsโ deprecated, and it has no effect ๐ฅ-mslow-flash-dataโ assumes loading data from flash is slower than fetching instructions ๐ So literal loads are minimized for better performance. This option is only supported when compiling for ARMv7 M-profile, and it's off by default. It conflicts with-mword-relocations.
-masm-syntax-unified okay so this one's about inline assembler syntax ๐ It tells GCC to assume the inline assembler is using unified asm syntax. The default is currently off, which implies divided syntax. This option has no impact on Thumb2 ๐ฆ but heads up, this may change in future releases of GCC. Divided syntax should be considered deprecated ๐ญ
-mrestrict-it bestie, this one restricts generation of IT blocks so they conform to the rules of ARMv8-A โจ IT blocks can only contain a single 16-bit instruction from a select set of instructions. It's on by default for ARMv8-A Thumb mode ๐
-mprint-tune-info prints CPU tuning information as a comment in the assembler file ๐ธ This is only used for regression testing of the compiler and is not intended for ordinary use when compiling code ๐ It's disabled by default.
-mverbose-cost-dump enables verbose cost model dumping in the debug dump files ๐ง This one is provided for debugging the compiler, so it's more of a behind-the-scenes thing ๐
-mpure-code do not allow constant data to be placed in code sections ๐ฅ Additionally, when compiling for ELF object format, it gives all text sections the ELF processor-specific section attribute SHF_ARM_PURECODE. This option is only available when generating non-PIC code for M-profile targets ๐
-mcmse generates secure code as per the "ARMv8-M Security Extensions: Requirements on Development Tools Engineering Specification" ๐ You can find that spec at <https://developer.arm.com/documentation/ecm0359818/latest/> ๐ฆ
-mfix-cmse-cve-2021-35465 mitigates a potential security issue with the "VLLDM" instruction on some M-profile devices when using CMSE (CVE-2021-365465) ๐ This option is enabled by default when -mcpu= is used with "cortex-m33", "cortex-m35p" or "cortex-m55" ๐ Use -mno-fix-cmse-cve-2021-35465 to disable the mitigation.
-mfdpic -mno-fdpic selects the FDPIC ABI, which uses 64-bit function descriptors to represent pointers to functions ๐ When the compiler is configured for "arm-*-uclinuxfdpiceabi" targets, this option is on by default and implies -fPIE if none of the PIC/PIE-related options is provided. On other targets, it only enables the FDPIC-specific code generation features, so you'll need to explicitly provide the PIC/PIE-related options as needed ๐ซถ
ngl the static linking part is important: static linking is not supported because it would still involve the dynamic linker when the program self-relocates โ ๏ธ If that behavior is acceptable, use -static and -Wl,-dynamic-linker options ๐
The opposite -mno-fdpic option is useful (and required) for building the Linux kernel using the same ("arm-*-uclinuxfdpiceabi") toolchain as the one used to build the userland programs ๐
โจ
AVR Options
These options are defined for AVR implementations ๐ง
-mmcu=mcu specifies the Atmel AVR instruction set architecture (ISA) or MCU type ๐ฆ
The default for this option is avr2 ๐
GCC supports the following AVR devices and ISAs ๐
- "avr2" โ "Classic" devices with up to 8 KiB of program memory. MCU =
"attiny22","attiny26","at90s2313","at90s2323","at90s2333","at90s2343","at90s4414","at90s4433","at90s4434","at90c8534","at90s8515","at90s8535". - "avr25" โ "Classic" devices with up to 8 KiB of program memory and with the "MOVW" instruction. MCU =
"attiny13","attiny13a","attiny24","attiny24a","attiny25","attiny261","attiny261a","attiny2313","attiny2313a","attiny43u","attiny44","attiny44a","attiny45","attiny48","attiny441","attiny461","attiny461a","attiny4313","attiny84","attiny84a","attiny85","attiny87","attiny88","attiny828","attiny841","attiny861","attiny861a","ata5272","ata6616c","at86rf401". - "avr3" โ "Classic" devices with 16 KiB up to 64 KiB of program memory. MCU =
"at76c711","at43usb355". - "avr31" โ "Classic" devices with 128 KiB of program memory. MCU =
"atmega103","at43usb320". - "avr35" โ "Classic" devices with 16 KiB up to 64 KiB of program memory and with the "MOVW" instruction. MCU =
"attiny167","attiny1634","atmega8u2","atmega16u2","atmega32u2","ata5505","ata6617c","ata664251","at90usb82","at90usb162". - "avr4" โ "Enhanced" devices with up to 8 KiB of program memory. MCU =
"atmega48","atmega48a","atmega48p","atmega48pa","atmega48pb","atmega8","atmega8a","atmega8hva","atmega88","atmega88a","atmega88p","atmega88pa","atmega88pb","atmega8515","atmega8535","ata6285","ata6286","ata6289","ata6612c","at90pwm1","at90pwm2","at90pwm2b","at90pwm3","at90pwm3b","at90pwm81". - "avr5" โ "Enhanced" devices with 16 KiB up to 64 KiB of program memory. MCU =
"atmega16","atmega16a","atmega16hva","atmega16hva2","atmega16hvb","atmega16hvbrevb","atmega16m1","atmega16u4","atmega161","atmega162","atmega163","atmega164a","atmega164p","atmega164pa","atmega165","atmega165a","atmega165p","atmega165pa","atmega168","atmega168a","atmega168p","atmega168pa","atmega168pb","atmega169","atmega169a","atmega169p","atmega169pa","atmega32","atmega32a","atmega32c1","atmega32hvb","atmega32hvbrevb","atmega32m1","atmega32u4","atmega32u6","atmega323","atmega324a","atmega324p","atmega324pa","atmega325","atmega325a","atmega325p","atmega325pa","atmega328","atmega328p","atmega328pb","atmega329","atmega329a","atmega329p","atmega329pa","atmega3250","atmega3250a","atmega3250p","atmega3250pa","atmega3290","atmega3290a","atmega3290p","atmega3290pa","atmega406","atmega64","atmega64a","atmega64c1","atmega64hve","atmega64hve2","atmega64m1","atmega64rfr2","atmega640","atmega644","atmega644a","atmega644p","atmega644pa","atmega644rfr2","atmega645","atmega645a","atmega645p","atmega649","atmega649a","atmega649p","atmega6450","atmega6450a","atmega6450p","atmega6490","atmega6490a","atmega6490p","ata5795","ata5790","ata5790n","ata5791","ata6613c","ata6614q","ata5782","ata5831","ata8210","ata8510","ata5702m322","at90pwm161","at90pwm216","at90pwm316","at90can32","at90can64","at90scr100","at90usb646","at90usb647","at94k","m3000". - "avr51" โ "Enhanced" devices with 128 KiB of program memory. MCU =
"atmega128","atmega128a","atmega128rfa1","atmega128rfr2","atmega1280","atmega1281","atmega1284","atmega1284p","atmega1284rfr2","at90can128","at90usb1286","at90usb1287". - "avr6" โ "Enhanced" devices with 3-byte PC, i.e. with more than 128 KiB of program memory. MCU =
"atmega256rfr2","atmega2560","atmega2561","atmega2564rfr2". - "avrxmega2" โ "XMEGA" devices with more than 8 KiB and up to 64 KiB of program memory. MCU =
"atxmega8e5","atxmega16a4","atxmega16a4u","atxmega16c4","atxmega16d4","atxmega16e5","atxmega32a4","atxmega32a4u","atxmega32c3","atxmega32c4","atxmega32d3","atxmega32d4","atxmega32e5". - "avrxmega3" โ "XMEGA" devices with up to 64 KiB of combined program memory and RAM, and with program memory visible in the RAM address space. MCU =
"attiny202","attiny204","attiny212","attiny214","attiny402","attiny404","attiny406","attiny412","attiny414","attiny416","attiny417","attiny804","attiny806","attiny807","attiny814","attiny816","attiny817","attiny1604","attiny1606","attiny1607","attiny1614","attiny1616","attiny1617","attiny3214","attiny3216","attiny3217","atmega808","atmega809","atmega1608","atmega1609","atmega3208","atmega3209","atmega4808","atmega4809". - "avrxmega4" โ "XMEGA" devices with more than 64 KiB and up to 128 KiB of program memory. MCU =
"atxmega64a3","atxmega64a3u","atxmega64a4u","atxmega64b1","atxmega64b3","atxmega64c3","atxmega64d3","atxmega64d4". - "avrxmega5" โ "XMEGA" devices with more than 64 KiB and up to 128 KiB of program memory and more than 64 KiB of RAM. MCU =
"atxmega64a1","atxmega64a1u". - "avrxmega6" โ "XMEGA" devices with more than 128 KiB of program memory. MCU =
"atxmega128a3","atxmega128a3u","atxmega128b1","atxmega128b3","atxmega128c3","atxmega128d3","atxmega128d4","atxmega192a3","atxmega192a3u","atxmega192c3","atxmega192d3","atxmega256a3","atxmega256a3b","atxmega256a3bu","atxmega256a3u","atxmega256c3","atxmega256d3","atxmega384c3","atxmega384d3". - "avrxmega7" โ "XMEGA" devices with more than 128 KiB of program memory and more than 64 KiB of RAM. MCU =
"atxmega128a1","atxmega128a1u","atxmega128a4u". - "avrtiny" โ "TINY" Tiny core devices with 512 B up to 4 KiB of program memory. MCU =
"attiny4","attiny5","attiny9","attiny10","attiny20","attiny40". - "avr1" โ This ISA is implemented by the minimal AVR core and supported for assembler only. MCU =
"attiny11","attiny12","attiny15","attiny28","at90s1200".
-mabsdata assumes that all data in static storage can be accessed by LDS / STS instructions ๐ธ This option only has an effect on reduced Tiny devices like ATtiny40. See also the "absdata" AVR Variable Attributes, variable attribute ๐
-maccumulate-args accumulates outgoing function arguments and acquires/releases the needed stack space for outgoing function arguments once in the function prologue/epilogue โจ Without this option, outgoing arguments are pushed before calling a function and popped afterwards.
Popping the arguments after the function call can be expensive on AVR, so accumulating the stack space might lead to smaller executables because arguments need not be removed from the stack after such a function call ๐ง
This option can lead to reduced code size for functions that perform several calls to functions that get their arguments on the stack, like calls to printf-like functions ๐
-mbranch-cost=cost sets the branch costs for conditional branch instructions to cost ๐ฆ Reasonable values for cost are small, non-negative integers. The default branch cost is 0 ๐
-mcall-prologuesโ okay so this one tells GCC to expand function prologues and epilogues into calls to the right subroutines ๐ง Your code size gets smaller, which is giving efficiency โจ-mdouble=bits,-mlong-double=bitsโ these set how many bits thedoubleorlong doubletype gets, respectively ๐ The allowed values are32and64. Whether a particular value is allowed depends on the--with-double=and--with-long-double=configure options (https://gcc.gnu.org/install/configure.html#avr), and the same rule applies to the default values of these options ๐ค-mgas-isr-prologuesโ ISRs are allowed to use the__gcc_isrpseudo instruction, which is supported by GNU Binutils ๐ฆ If this option is on, you can still turn the feature off for individual ISRs with theno_gccisrfunction attribute (see AVR Function Attributes). It's switched on by default when optimization is on (but not with-Og,@pxref{Optimize Options}), and only if GNU Binutils supports PR21683 (https://sourceware.org/PR21683) ๐ธ-mint8โ this makesintan 8-bit integer ๐ All the sizes shift with it: acharis 1 byte, anintis 1 byte, alongis 2 bytes, and along longis 4 bytes. Smaller code size is the payoff.
๐จ Heads up bestie: this option does NOT conform to the C standards, even though it gives you smaller code size.
-mmain-is-OS_taskโ do not save registers inmain๐ It has the same effect as attaching theOS_taskattribute tomain(see AVR Function Attributes). It's turned on by default when optimization is on.-mn-flash=numโ assume the flash memory isnumtimes 64 KiB big ๐ง-mno-interruptsโ the generated code is not compatible with hardware interrupts, but the code size is smaller ๐
๐จ Do not use this one if your code needs interrupts. The generated code is not compatible with them.
-mrelaxโ this tries to swapCALL(orJMP) for the shorterRCALL(orRJMP) instruction whenever that's possible โจ Setting-mrelaxjust adds the--mlink-relaxoption to the assembler's command line and the--relaxoption to the linker's command line.
Jump relaxing is done by the linker, because jump offsets aren't known until the code gets located ๐ฆ So the assembler code the compiler generates stays the same, but the instructions in the executable may differ from the ones in the assembler code.
Relaxing must be turned on if linker stubs are needed. See the section on "EIND" and linker stubs below ๐
-mrmwโ assume the device supports the Read-Modify-Write instructionsXCH,LAC,LASandLAT๐ฅ-mshort-callsโ assumeRJMPandRCALLcan target the whole program memory ๐
This option is used internally for multilib selection. It's not an optimization option, and you don't need to set it by hand ๐
-msp8โ treat the stack pointer register as an 8-bit register, aka assume the high byte of the stack pointer is zero ๐ In general, you don't need to set this one by hand.
This option is used internally by the compiler to select and build multilibs for the avr2 and avr25 architectures. These architectures mix devices with and without SPH. For any setting other than -mmcu=avr2 or -mmcu=avr25, the compiler driver adds or removes this option from the compiler proper's command line, because the compiler then knows whether the device or architecture has an 8-bit stack pointer (and therefore no SPH register) or not โจ
-mstrict-Xโ use the address registerXthe way the hardware intends ๐ That meansXis only used in indirect, post-increment or pre-decrement addressing.
Without this option, the X register can be used the same way as Y or Z, which then gets emulated with extra instructions. For example, loading a value with X+const addressing, where const is a small non-negative number less than 64, into a register Rn is done like this:
adiw r26, const ; X += const
ld <Rn>, X ; <Rn> = *X
sbiw r26, const ; X -= const
-mtiny-stackโ only change the lower 8 bits of the stack pointer ๐ง-mfract-convert-truncateโ allows truncation instead of rounding towards zero for fractional fixed-point types ๐ซถ-nodevicelibโ don't link against AVR-LibC's device-specific librarylib<mcu>.a๐ฆ-nodevicespecsโ this stops the driver from adding-specs=device-specs/specs-mcuto its command line ๐ Now YOU are in charge of giving the subprocesses (compiler proper, assembler and linker) the right command line options. That means you have to supply your own private device specs file with-specs=path-to-specs-file. There's no more need for-mmcu=mcu.
This option can also replace the older way of specifying custom device-specs files. That old way needed -B some-path to point to a directory containing a folder named "device-specs", and that folder had to contain a specs file named "specs-mcu", where mcu was whatever you set with -mmcu=mcu ๐ธ
-Waddr-space-convertโ warns about conversions between address spaces where the resulting address space isn't contained in the incoming address space โญ-Wmisspelled-isrโ warns if an ISR is misspelled, i.e. without the__vectorprefix. It's enabled by default ๐
โจ "EIND" and Devices with More Than 128 Ki Bytes of Flash ๐ฐ
Pointers in the implementation are 16 bits wide ๐ The address of a function or label gets represented as a word address, so indirect jumps and calls can target any code address in the range of 64 Ki words.
To make indirect jumps work on devices with more than 128 Ki bytes of program memory, there's a special function register called "EIND". It serves as the most significant part of the target address when the EICALL or EIJMP instructions are used ๐ฅ
Indirect jumps and calls on these devices are handled as follows by the compiler, and they come with some limitations:
- The compiler never sets
EIND. - The compiler uses
EINDimplicitly inEICALL/EIJMPinstructions, or it might readEINDdirectly in order to emulate an indirect call/jump by means of aRETinstruction. - The compiler assumes that
EINDnever changes during the startup code or during the application. In particular,EINDis not saved/restored in function or interrupt service routine prologue/epilogue. - For indirect calls to functions and computed goto, the linker generates stubs. Stubs are jump pads, sometimes also called trampolines. So the indirect call/jump lands on such a stub, and the stub contains a direct jump to the desired address ๐ฆ
- Linker relaxation must be turned on so that the linker generates the stubs correctly in all situations. See the compiler option
-mrelaxand the linker option--relax.
โ ๏ธ There are corner cases where the linker is supposed to generate stubs but aborts without relaxation and without a helpful error message. Yikes.
- The default linker script is arranged for code with
EIND = 0. If your code is supposed to work for a setup withEIND != 0, you'll need a custom linker script to place the sections whose name starts with.trampolinesinto the segment whereEINDpoints to ๐ง - The startup code from libgcc never sets
EIND. Notice that the startup code is a blend of code from libgcc and AVR-LibC. For the impact of AVR-LibC onEIND, see the AVR-LibC user manual (http://nongnu.org/avr-libc/user-manual/) ๐ - It's legit for user-specific startup code to set up
EINDearly, for example with initialization code located in section.init3. That code runs before the general startup code that initializes RAM and calls constructors, but after the bit of AVR-LibC startup code that setsEINDto the segment where the vector table is located ๐ซถ
#include <avr/io.h>
static void
__attribute__((section(".init3"),naked,used,no_instrument_function))
init3_set_eind (void)
{
__asm volatile ("ldi r24,pm_hh8(__trampolines_start)\n\t"
"out %i0,r24" :: "n" (&EIND) : "r24","memory");
}
The __trampolines_start symbol is defined in the linker script โจ
- Stubs are generated automatically by the linker if the following two conditions are met:
- The address of a label is taken by means of the
gsmodifier (short for generate stubs), like so:
- The address of a label is taken by means of the
LDI r24, lo8(gs(<func>))
LDI r25, hi8(gs(<func>))
- The final location of that label is in a code segment outside the segment where the stubs are located.
- The compiler emits such
gsmodifiers for code labels in the following situations:- Taking the address of a function or code label.
- Computed goto.
- If the prologue-save function is used, see the
-mcall-prologuescommand-line option. - Switch/case dispatch tables. If you do not want such dispatch tables, you can specify the
-fno-jump-tablescommand-line option. - C and C++ constructors/destructors called during startup/shutdown.
- If the tools hit a
gs()modifier explained above.
- Jumping to non-symbolic addresses like so is not supported ๐
int main (void)
{
/* Call function at word address 0x2 */
return ((int(*)(void)) 0x2)();
}
Instead, a stub has to be set up, i.e. the function has to be called through a symbol (func_4 in the example):
int main (void)
{
extern int func_4 (void);
/* Call function at byte address 0x4 */
return func_4();
}
and the application has to be linked with -Wl,--defsym,func_4=0x4. Alternatively, func_4 can be defined in the linker script ๐
โจ Handling of the "RAMPD", "RAMPX", "RAMPY" and "RAMPZ" Special Function Registers ๐
Some AVR devices support memories larger than the 64 KiB range that can be accessed with 16-bit pointers ๐ To access memory locations outside this 64 KiB range, the content of a RAMP register is used as the high part of the address. The X, Y and Z address registers are concatenated with the RAMPX, RAMPY and RAMPZ special function registers, respectively, to get a wide address. Similarly, RAMPD is used together with direct addressing ๐ง
- The startup code initializes the
RAMPspecial function registers with zero ๐ซถ - ๐ธ Okay so if you use an AVR named address space other than generic or
__flash, GCC setsRAMPZas needed before the operation. Prep work, but make it cute โจ - ๐
If the device supports RAM bigger than 64 KiB and the compiler needs to change
RAMPZto pull off an operation,RAMPZgets reset to zero afterwards. Clean up after yourself, bestie ๐งน - ๐ฆ If the device comes with a specific
RAMPregister, the ISR prologue/epilogue saves and restores that SFR, and initializes it with zero in case the ISR code might (implicitly) use it. Protecting the vibe ๐ซถ
๐จ RAM larger than 64 KiB is not supported by GCC for AVR targets. If you use inline assembler to read from locations outside the 16-bit address range and change one of the RAMP registers, you must reset it to zero after the access. Do not skip this, it's giving disaster ๐
๐ AVR Built-in Macros ๐
GCC defines several built-in macros so your code can check whether features are present or absent, which is literally so iconic ๐ฅ Almost all of the following are deduced from device capabilities, so they get triggered by the -mmcu= command-line option.
For even more AVR-specific built-in macros, check out AVR Named Address Spaces and AVR Built-in Functions ๐ง
__AVR_ARCH__โ A built-in macro that resolves to a decimal number identifying the architecture. It depends on the-mmcu=mcuoption. The possible values are below โจ
2, 25, 3, 31, 35, 4, 5, 51, 6
for mcu="avr2", "avr25", "avr3", "avr31", "avr35", "avr4", "avr5", "avr51", "avr6",
respectively
100, 102, 103, 104, 105, 106, 107
for mcu="avrtiny", "avrxmega2", "avrxmega3", "avrxmega4", "avrxmega5",
"avrxmega6", "avrxmega7", respectively
If mcu specifies a device, this built-in macro gets set accordingly. For example, with -mmcu=atmega8 the macro is defined to 4 ๐
__AVR_Device__โ Setting-mmcu=devicedefines this built-in macro, which reflects the device's name. For example,-mmcu=atmega8defines__AVR_ATmega8__, and-mmcu=attiny261adefines__AVR_ATtiny261A__, etc. ๐- The names follow the scheme
__AVR_Device__, where Device is the device name from the AVR user manual. The difference between Device in the built-in macro and device in-mmcu=deviceis that the latter is always lowercase. - If device is not an actual device but just a core architecture like
avr51, this macro is not defined.
- The names follow the scheme
__AVR_DEVICE_NAME__โ Setting-mmcu=devicedefines this built-in macro to the device's name. For example, with-mmcu=atmega8the macro is defined to"atmega8".- If device is not an actual device but just a core architecture like
avr51, this macro is not defined.
- If device is not an actual device but just a core architecture like
__AVR_XMEGA__โ The device or architecture belongs to the XMEGA family of devices ๐__AVR_HAVE_ELPM__โ The device has theELPMinstruction ๐ฆ__AVR_HAVE_ELPMX__โ The device has theELPM Rn,ZandELPM Rn,Z+instructions ๐ฆ__AVR_HAVE_MOVW__โ The device has theMOVWinstruction for 16-bit register-to-register moves ๐__AVR_HAVE_LPMX__โ The device has theLPM Rn,ZandLPM Rn,Z+instructions ๐ธ__AVR_HAVE_MUL__โ The device has a hardware multiplier โจ__AVR_HAVE_JMP_CALL__โ The device has theJMPandCALLinstructions. This is the case for devices with more than 8 KiB of program memory ๐ง__AVR_HAVE_EIJMP_EICALL__,__AVR_3_BYTE_PC__โ The device has theEIJMPandEICALLinstructions. This is the case for devices with more than 128 KiB of program memory. It also means the program counter (PC) is 3 bytes wide ๐__AVR_2_BYTE_PC__โ The program counter (PC) is 2 bytes wide. This is the case for devices with up to 128 KiB of program memory ๐__AVR_HAVE_8BIT_SP__,__AVR_HAVE_16BIT_SP__โ The stack pointer (SP) register is treated by the compiler as an 8-bit or 16-bit register, respectively. Defining these macros is affected by-mtiny-stack๐__AVR_HAVE_SPH__,__AVR_SP8__โ The device has the SPH (high part of stack pointer) special function register, or has an 8-bit stack pointer, respectively. Defining these macros is affected by-mmcu=, and in the cases of-mmcu=avr2and-mmcu=avr25also by-msp8๐__AVR_HAVE_RAMPD__,__AVR_HAVE_RAMPX__,__AVR_HAVE_RAMPY__,__AVR_HAVE_RAMPZ__โ The device has theRAMPD,RAMPX,RAMPY, orRAMPZspecial function register, respectively ๐ฆ__NO_INTERRUPTS__โ This macro reflects the-mno-interruptscommand-line option ๐ซถ__AVR_ERRATA_SKIP__,__AVR_ERRATA_SKIP_JMP_CALL__โ Some AVR devices (AT90S8515, ATmega103) must not skip 32-bit instructions because of a hardware erratum. The skip instructions areSBRS,SBRC,SBIS,SBIC, andCPSE. The second macro is only defined if__AVR_HAVE_JMP_CALL__is also set ๐__AVR_ISA_RMW__โ The device has Read-Modify-Write instructions (XCH,LAC,LAS, andLAT) ๐ฅ__AVR_SFR_OFFSET__=offsetโ Instructions that can address I/O special function registers directly, likeIN,OUT,SBI, etc., may use a different address than an instruction accessing RAM, likeLDorSTS. This offset depends on the device architecture and has to be subtracted from the RAM address to get the respective I/O address ๐ง__AVR_SHORT_CALLS__โ The-mshort-callscommand-line option is set ๐ธ__AVR_PM_BASE_ADDRESS__=addrโ Some devices support reading from flash memory usingLD*instructions. The flash memory shows up in the data address space at an offset of__AVR_PM_BASE_ADDRESS__. If this macro is not defined, this feature is not available. If it is defined, the address space is linear and there is no need to put.rodatainto RAM. This is handled by the default linker description file, and it is currently available foravrtinyandavrxmega3. Even more convenient, there is no need to use address spaces like__flash, or features like the attributeprogmemandpgm_read_*๐__WITH_AVRLIBC__โ The compiler is configured to be used together with AVR-Libc. See the--with-avrlibcconfigure option ๐__HAVE_DOUBLE_MULTILIB__โ Defined if-mdouble=acts as a multilib option ๐__HAVE_DOUBLE32__,__HAVE_DOUBLE64__โ Defined if the compiler supports 32-bitdoubleor 64-bitdouble, respectively. The actual layout is specified by option-mdouble=โจ__DEFAULT_DOUBLE__โ The size in bits ofdoubleif-mdouble=is not set. To test the layout ofdoublein a program, use the built-in macro__SIZEOF_DOUBLE__๐__HAVE_LONG_DOUBLE32__,__HAVE_LONG_DOUBLE64__,__HAVE_LONG_DOUBLE_MULTILIB__,__DEFAULT_LONG_DOUBLE__โ Same as above, but forlong doubleinstead ofdouble๐__WITH_DOUBLE_COMPARISON__โ Reflects the--with-double-comparison={tristate|bool|libf7}configure option (https://gcc.gnu.org/install/configure.html#avr), and is defined to2or3๐ฆ__WITH_LIBF7_LIBGCC__,__WITH_LIBF7_MATH__,__WITH_LIBF7_MATH_SYMBOLS__โ Reflects the--with-libf7={libgcc|math|math-symbols}configure option (https://gcc.gnu.org/install/configure.html#avr) ๐ซถ
๐ฆ Blackfin Options ๐ฆ
-mcpu=cpu[-sirevision]โ Specifies the name of the target Blackfin processor. Right now,cpucan be one ofbf512,bf514,bf516,bf518,bf522,bf523,bf524,bf525,bf526,bf527,bf531,bf532,bf533,bf534,bf536,bf537,bf538,bf539,bf542,bf544,bf547,bf548,bf549,bf542m,bf544m,bf547m,bf548m,bf549m,bf561, orbf592๐- The optional
sirevisionspecifies the silicon revision of the target Blackfin processor. Any workarounds available for that silicon revision get enabled. Ifsirevisionisnone, no workarounds are enabled. Ifsirevisionisany, all workarounds for the targeted processor are enabled. - The
__SILICON_REVISION__macro is defined to two hexadecimal digits representing the major and minor numbers in the silicon revision. Ifsirevisionisnone,__SILICON_REVISION__is not defined. Ifsirevisionisany,__SILICON_REVISION__is defined to be0xffff. If this optionalsirevisionis not used, GCC assumes the latest known silicon revision of the targeted Blackfin processor. - GCC defines a preprocessor macro for the specified
cpu. For thebfin-elftoolchain, this option causes the hardware BSP provided by libgloss to be linked in if-msimis not given. - Without this option,
bf532is used as the processor by default. - Heads up: support for
bf561is incomplete. Forbf561, only the preprocessor macro is defined โ ๏ธ
- The optional
-msimโ Specifies that the program will be run on the simulator. This causes the simulator BSP provided by libgloss to be linked in. This option only has effect for thebfin-elftoolchain. Certain other options, such as-mid-shared-libraryand-mfdpic, imply-msim๐-momit-leaf-frame-pointerโ Don't keep the frame pointer in a register for leaf functions. This skips the instructions that save, set up, and restore frame pointers, and it frees up an extra register in leaf functions ๐ง-mspecld-anomalyโ When enabled, the compiler makes sure the generated code does not contain speculative loads after jump instructions. If this option is used,__WORKAROUND_SPECULATIVE_LOADSis defined ๐-mno-specld-anomalyโ Don't generate extra code to prevent speculative loads from occurring ๐-mcsync-anomalyโ When enabled, the compiler makes sure the generated code does not containCSYNCorSSYNCinstructions too soon after conditional branches. If this option is used,__WORKAROUND_SPECULATIVE_SYNCSis defined ๐ซถ-mno-csync-anomalyโ Don't generate extra code to preventCSYNCorSSYNCinstructions from occurring too soon after a conditional branch ๐-mlow64kโ When enabled, the compiler is free to take advantage of the knowledge that the entire program fits into the low 64k of memory ๐-mno-low64kโ Assume that the program is arbitrarily large. This is the default ๐ธ-mstack-check-l1โ Does stack checking using information placed into L1 scratchpad memory by the uClinux kernel ๐-mid-shared-libraryโ Generates code that supports shared libraries via the library ID method. This allows for execute in place and shared libraries in an environment without virtual memory management. This option implies-fPIC. With abfin-elftarget, this option implies-msim๐ฆ-mno-id-shared-libraryโ okay so this one is the default ๐ It tells the compiler NOT to assume ID-based shared libraries are in use. Main character behavior ๐-mleaf-id-shared-libraryโ this one supports shared libraries through the library ID method, but it assumes the library or executable won't link against any other ID shared libraries ๐ฆ Bestie, that assumption lets the compiler use faster code for jumps and calls โจ-mno-leaf-id-shared-libraryโ the opposite vibe ๐ It doesn't assume the code avoids linking with ID shared libraries, so the jump and call instructions come out slower ๐ข-mshared-library-id=nโ sets the identification number of the ID-based shared library being compiled ๐ข Using0gives you more compact code ๐ Any other value forces that number onto the current library, but it's no more space- or time-efficient than just leaving this option out ๐คทโโ๏ธ-msep-dataโ lets the data segment live in a different area of memory from the text segment ๐ง This makes execute in place possible in an environment without virtual memory management, because it gets rid of relocations against the text section ๐-mno-sep-dataโ assumes the data segment sits right after the text segment ๐ธ This is the default.-mlong-calls,-mno-long-callsโ with-mlong-calls, the compiler loads the function's address into a register first, then makes a subroutine call through that register ๐ You need this if the target function is outside the 24-bit addressing range of the offset-based subroutine call instruction ๐ It's not enabled by default, and-mno-long-callsputs you back to the default behavior. Heads up: these switches have no effect on how function calls through function pointers are generated ๐-mfast-fpโ links with the fast floating-point library โก It relaxes some of the IEEE floating-point standard's rules for checking inputs against Not-a-Number (NAN), all in the name of performance ๐ฅ-minline-pltโ enables inlining of PLT entries in function calls to functions that aren't known to bind locally ๐ It has no effect without-mfdpicโจ-mmulticoreโ builds a standalone application for multicore Blackfin processors ๐ This makes the compiler use proper start files and link scripts that support multicore, and it defines the macro"__BFIN_MULTICORE"๐ It can only be used with-mcpu=bf561[-sirevision]๐
You can pair it with -mcorea or -mcoreb for the one-application-per-core programming model ๐ฏโโ๏ธ Without either of those, you get the single-application/dual-core model. In that model, the main function of Core B should be named "coreb_main" ๐ If you skip -mmulticore entirely, you get the single-core application programming model ๐ซถ
-mcoreaโ builds a standalone application for Core A of BF561 in the one-application-per-core model ๐ Start files and link scripts support Core A, and the macro"__BFIN_COREA"gets defined. This option can only be used together with-mmulticore๐ฅ-mcorebโ same energy, but for Core B of BF561 ๐ฆ It defines"__BFIN_COREB", and when you use it,"coreb_main"should be used instead of"main"๐ This one also can only be used together with-mmulticoreโจ-msdramโ builds a standalone application for SDRAM ๐ง Start files and link scripts put the app into SDRAM, and the macro"__BFIN_SDRAM"is defined. The loader should initialize SDRAM before loading the application ๐-micplbโ assumes ICPLBs are enabled at run time ๐ง This affects certain anomaly workarounds. For Linux targets the default is to assume ICPLBs are enabled, but for standalone applications the default is off ๐ธ
๐ฆ C6X Options ๐ฆ
-march=nameโ specifies the name of the target architecture ๐ฏ GCC uses this to figure out what kinds of instructions it's allowed to emit when generating assembly code. The permissible names arec62x,c64x,c64x+,c67x,c67x+, andc674x๐-mbig-endianโ generates code for a big-endian target ๐-mlittle-endianโ generates code for a little-endian target ๐ This is the default โจ-msimโ picks startup files and a linker script that work with the simulator ๐งช-msdata=defaultโ puts small global and static data in the".neardata"section, which is pointed to by registerB14๐ Small uninitialized global and static data goes in the".bss"section, which sits right next to".neardata"๐ง Small read-only data goes in the".rodata"section ๐ Large pieces of data use the matching sections".fardata",".far", and".const"๐-msdata=allโ puts all data, not just the small objects, into the sections reserved for small data ๐ It uses addressing relative to theB14register to get at them ๐ซถ-msdata=noneโ makes no use of the small-data sections at all, and uses absolute addresses for all data ๐ All initialized global and static data goes in".fardata", all uninitialized data goes in".far", and all constant data goes in".const"๐ธ
๐ CRIS Options ๐
These options are defined specifically for the CRIS ports ๐ง
-march=architecture-type,-mcpu=architecture-typeโ generates code for the specified architecture ๐ The choices arev3,v8, andv10, which map to ETRAX 4, ETRAX 100, and ETRAX 100 LX respectively ๐ The default isv0, except forcris-axis-linux-gnu, where the default isv10๐-mtune=architecture-typeโ tunes everything applicable about the generated code to the given architecture-type โจ The one exception is the ABI and the set of available instructions, which stay the same ๐ฆ The choices are the same as for-march=architecture-type๐ซถ-mmax-stack-frame=nโ warns when the stack frame of a function goes overnbytes โ ๏ธ-metrax4,-metrax100โ these are synonyms for-march=v3and-march=v8respectively ๐ธ-mmul-bug-workaround,-mno-mul-bug-workaroundโ works around a bug in the"muls"and"mulu"instructions for CPU models where it applies ๐ง This option is active by default โ-mpdebugโ enables CRIS-specific verbose debug-related information in the assembly code ๐ It also turns off the#NO_APPformatted-code indicator that gets sent to the assembler at the start of the assembly file ๐-mcc-initโ don't use condition-code results from previous instructions ๐ โโ๏ธ Always emit compare and test instructions before using condition codes ๐-mno-side-effectsโ don't emit instructions with side effects in addressing modes other than post-increment ๐ง-mstack-align,-mno-stack-align,-mdata-align,-mno-data-align,-mconst-align,-mno-const-alignโ these arrange (or, with theno-versions, eliminate the arrangement of) alignment for the stack frame, individual data, and constants ๐ The alignment matches the maximum single data access size for the chosen CPU model ๐ฏ The default is 32-bit alignment, and ABI details like structure layout aren't affected by these options ๐-m32-bit,-m16-bit,-m8-bitโ similar to the stack, data, and const align options above ๐ These make the stack frame, writable data, and constants all 32-bit, 16-bit, or 8-bit aligned ๐ The default is 32-bit alignment ๐-mno-prologue-epilogue,-mprologue-epilogueโ with-mno-prologue-epilogue, the normal function prologue and epilogue that set up the stack frame are left out, and no return instructions or return sequences get generated ๐ญ
โ ๏ธ Only use this option together with visual inspection of the compiled code. No warnings or errors are generated when call-saved registers need saving, or when storage for local variables needs allocating. This one is dangerous if you're not checking the output yourself ๐
-mno-gotplt,-mgotpltโ with-fpicand-fPIC,-mno-gotpltmeans don't generate instruction sequences that load function addresses from the PLT part of the GOT, and-mgotpltmeans do generate them. Those sequences are used instead of the traditional calls to the PLT on other architectures ๐ฆ The default is-mgotplt๐ซถ-melfโ a legacy no-op option ๐ฐ๏ธ It's only recognized with thecris-axis-elfandcris-axis-linux-gnutargets.-mlinuxโ another legacy no-op option ๐ฐ๏ธ It's only recognized with thecris-axis-linux-gnutarget.-simโ recognized for thecris-axis-elftarget ๐งช It links with input-output functions from a simulator library. Code, initialized data, and zero-initialized data get allocated consecutively ๐ง-sim2โ like-sim, but it passes linker options to locate initialized data at0x40000000and zero-initialized data at0x80000000๐
๐ CR16 Options ๐
These options are defined specifically for the CR16 ports ๐ธ
-mmacโ enables the use of multiply-accumulate instructions โ๏ธ It's disabled by default ๐ โโ๏ธ-mcr16cplus,-mcr16cโ generates code for the CR16C or CR16C+ architecture ๐ The CR16C+ architecture is the default ๐-msimโ links the librarylibsim.a, which is compatible with the simulator ๐งช This only applies to the ELF compiler ๐ง-mint32โ chooses the integer type to be 32-bit wide ๐ข-mbit-opsโ generates"sbit"and"cbit"instructions for bit manipulations ๐ง-mdata-model=modelโ chooses a data model ๐ฆ The choices formodelarenear,far, ormedium, andmediumis the default ๐ Heads up though:faris not valid with-mcr16c, because the CR16C architecture doesn't support the far data model ๐
๐ C-SKY Options ๐
GCC supports these options when compiling for C-SKY V2 processors ๐ซถ
-march=archโ specifies the C-SKY target architecture ๐ฏ Valid values forarchareck801,ck802,ck803,ck807, andck810. The default isck810๐-mcpu=cpuโ okay so this is where you pick your C-SKY target processor ๐ The validcpuvalues areck801,ck801t,ck802,ck802t,ck802j,ck803,ck803h,ck803t,ck803ht,ck803f,ck803fh,ck803e,ck803eh,ck803et,ck803eht,ck803ef,ck803efh,ck803ft,ck803eft,ck803efht,ck803r1,ck803hr1,ck803tr1,ck803htr1,ck803fr1,ck803fhr1,ck803er1,ck803ehr1,ck803etr1,ck803ehtr1,ck803efr1,ck803efhr1,ck803ftr1,ck803eftr1,ck803efhtr1,ck803s,ck803st,ck803se,ck803sf,ck803sef,ck803seft,ck807e,ck807ef,ck807,ck807f,ck810e,ck810et,ck810ef,ck810eft,ck810,ck810v,ck810f,ck810t,ck810fv,ck810tv,ck810ft, andck810ftv๐-mbig-endian,-EB,-mlittle-endian,-ELโ pick your byte order, big-endian or little-endian ๐ธ Little-endian is the default, so you get that if you don't say anything โจ-mhard-float,-msoft-floatโ hardware or software floating-point, your call ๐ฆ Soft float is the default, so hardware only kicks in when you ask for it ๐-mdouble-float,-mno-double-floatโ when-mhard-floatis in effect, this turns on double-precision float instructions ๐ฅ It's on by default except when you're compiling for CK803.-mfdivdu,-mno-fdivduโ with-mhard-floatin effect, this turns on generation of "frecipd", "fsqrtd", and "fdivd" instructions ๐ง It's on by default except when compiling for CK803.-mfpu=fpuโ picks your floating-point processor ๐ This one only works with-mhard-float. The values arefpv2_sf(same as-mno-double-float -mno-fdivdu),fpv2(-mdouble-float -mno-divdu), andfpv2_divd(-mdouble-float -mdivdu).-melrw,-mno-elrwโ enables the extendedlrwinstruction ๐ It defaults to on for CK801 and off for everything else.-mistack,-mno-istackโ enables interrupt stack instructions. The default is off ๐ซถ
Heads up bestie:-mistackis required if you want to handle theinterruptandisrfunction attributes ๐จ
-mmpโ enables multiprocessor instructions, default off ๐-mcpโ enables coprocessor instructions, default off ๐ธ-mcacheโ the manual says this one enables coprocessor instructions too, and the default is off ๐-msecurityโ enables C-SKY security instructions, default off ๐-mtrustโ enables C-SKY trust instructions, default off ๐ฆ-mdsp,-medsp,-mvdspโ these enable C-SKY DSP, Enhanced DSP, or Vector DSP instructions, respectively ๐ They all default to off.-mdiv,-mno-divโ generates divide instructions. Default is off โจ-msmart,-mno-smartโ generates code for Smart Mode, which only uses registers numbered0-7so you can use 16-bit instructions ๐ This is ignored for CK801, where it's required behavior, and it defaults to on for CK802. For other targets, the default is off.-mhigh-registers,-mno-high-registersโ generates code using the high registers numbered16-31๐ This isn't supported on CK801, CK802, or CK803, but it's enabled by default for other processors.-manchor,-mno-anchorโ generates code using global anchor symbol addresses ๐ง-mpushpop,-mno-pushpopโ generates code using "push" and "pop" instructions ๐ This one defaults to on.-mmultiple-stld,-mstm,-mno-multiple-stld,-mno-stmโ generates code using "stm" and "ldm" instructions ๐ This isn't supported on CK801, but it's enabled by default on other processors.-mconstpool,-mno-constpoolโ creates constant pools in the compiler instead of handing that job off to the assembler ๐ This is the default and is required for correct code generation on CK801 and CK802. It's optional on other processors.-mstack-size,-mno-stack-sizeโ emits.stack_sizedirectives for each function in the assembly output โญ This defaults to off.-mccrt,-mno-ccrtโ generates code for the C-SKY compiler runtime instead of libgcc ๐ซถ This defaults to off.-mbranch-cost=nโ sets the branch costs to roughlyninstructions ๐ฆ The default is1.-msched-prolog,-mno-sched-prologโ permits scheduling of function prologue and epilogue sequences ๐ Heads up, this can give you code that isn't compliant with the C-SKY V2 ABI prologue requirements, and that code can't be debugged or backtraced.
Using -msched-prolog can produce code that cannot be debugged or backtraced, so only flip it on if you know what you're doing ๐ It's disabled by default.
โจ Darwin Options โจ
These options are defined for all architectures running the Darwin operating system ๐
FSF GCC on Darwin doesn't make "fat" object files. It makes an object file for the single architecture that GCC was built to target ๐
Apple's GCC on Darwin does make "fat" files if you use multiple -arch options. It does that by running the compiler or linker multiple times and joining the results together with lipo ๐ฅ
The subtype of the file it creates (like ppc7400, ppc970, or i686) is determined by the flags that specify the ISA GCC is targeting, like -mcpu or -march ๐ The -force_cpusubtype_ALL option can be used to override this.
The Darwin tools act differently when they hit an ISA mismatch ๐ The assembler, as, only lets you use instructions that are valid for the subtype of the file it's generating. So you can't put 64-bit instructions in a ppc750 object file, period ๐
The linker for shared libraries, /usr/bin/libtool, fails and prints an error if you ask it to create a shared library with a less restrictive subtype than its input files. For example, trying to put a ppc970 object file in a ppc7400 library is a no-go ๐ The linker for executables, ld, quietly gives the executable the most restrictive subtype of any of its input files ๐คซ
-Fdirโ adds the framework directorydirto the head of the list of directories searched for header files ๐ธ These directories are interleaved with the ones from-Ioptions and get scanned left-to-right.- A framework directory is a directory with frameworks in it. ๐ง
- A framework is a directory with a
Headersand/orPrivateHeadersdirectory directly inside it, and its name ends in.framework. Its name is that directory's name without the.frameworkpart. Headers for the framework are found in one of those two directories, andHeadersgets searched first ๐ - A subframework is a framework directory that lives in a framework's
Frameworksdirectory. Includes of subframework headers can only show up in a header of the framework that contains the subframework, or in a sibling subframework header. Two subframeworks are siblings if they're in the same framework โจ - A subframework shouldn't have the same name as a framework, and a warning gets issued if you break that rule โ ๏ธ Right now a subframework can't have subframeworks of its own. The mechanism might be extended to support that later.
- The standard frameworks live in
/System/Library/Frameworksand/Library/Frameworks๐ฆ - An example include looks like
"#include <Framework/header.h>", whereFrameworkis the framework's name andheader.his found in itsPrivateHeadersorHeadersdirectory ๐
-iframeworkdirโ like-F, except the directory is treated as a system directory ๐ซถ The big difference is that with-iframework, the compiler doesn't warn about constructs in header files found viadir. This option is only valid for the C family of languages.-gusedโ emits debugging information for symbols that are used ๐ For the stabs debugging format, this enables-feliminate-unused-debug-symbols. It's on by default, so ON it stays โจ-gfullโ emits debugging information for all symbols and types ๐-mmacosx-version-min=versionโ the earliest MacOS X version this executable will run on isversion๐ Typical values are10.1,10.2, and10.3.9.
If the compiler was built to use the system's headers by default, the default for this option is the system version the compiler is running on. Otherwise, the default is to make choices that are compatible with as many systems and code bases as possible ๐ง
-mkernelโ enables kernel development mode ๐ The-mkerneloption sets-static,-fno-common,-fno-use-cxa-atexit,-fno-exceptions,-fno-non-call-exceptions,-fapple-kext,-fno-weak, and-fno-rtti, where applicable. For PowerPC targets, this mode also sets-mno-altivec,-msoft-float,-fno-builtin, and-mlong-branch๐-mone-byte-boolโ overrides the defaults for "bool" so thatsizeof(bool)==1๐ By default,sizeof(bool)is 4 when compiling for Darwin/PowerPC and 1 when compiling for Darwin/x86. That means this option does nothing on x86 ๐
Warning: -mone-byte-bool makes GCC generate code that isn't binary compatible with code generated without that switch ๐จ You may need to recompile all the other modules in a program, including system libraries. Only use this switch to conform to a non-default data model.
-mfix-and-continue,-ffix-and-continue,-findirect-dataโ generates code for fast turnaround development ๐ฅ That's the kind of thing that lets GDB dynamically load.ofiles into programs that are already running โจ-findirect-dataand-ffix-and-continueare only here for backwards compatibility.-all_loadโ loads all members of static archive libraries ๐ Seeman ld(1)for more information.-arch_errors_fatalโ makes errors about files with the wrong architecture fatal ๐-bind_at_loadโ marks the output file so the dynamic linker binds all undefined references when the file is loaded or launched ๐ธ-bundleโ produces a Mach-o bundle format file ๐ง Seeman ld(1)for more information.-bundle_loader executableโ specifies the executable that will load the build output file being linked ๐ฆ Seeman ld(1)for more information.-dynamiclibโ when you pass this, GCC produces a dynamic library instead of an executable when linking, using the Darwinlibtoolcommand ๐-force_cpusubtype_ALLโ gives GCC's output file the ALL subtype, instead of one controlled by the-mcpuor-marchoption ๐
Okay so these are the Darwin linker options, and they're giving "pass it along and don't ask questions" energy ๐ Here's the whole guest list, bestie. A few of them show up twice, and I kept every single one ๐ซถ
-allowable_client client_name-client_name-compatibility_version-current_version-dead_strip-dependency-file-dylib_file-dylinker_install_name-dynamic-exported_symbols_list-filelist-flat_namespace-force_flat_namespace-headerpad_max_install_names-image_base-init-install_name-keep_private_externs-multi_module-multiply_defined-multiply_defined_unused-noall_load-no_dead_strip_inits_and_terms-nofixprebinding-nomultidefs-noprebind-noseglinkedit-pagezero_size-prebind-prebind_all_twolevel_modules-private_bundle-read_only_relocs-sectalign-sectobjectsymbols-whyload-seg1addr-sectcreate-sectobjectsymbols-sectorder-segaddr-segs_read_only_addr-segs_read_write_addr-seg_addr_table-seg_addr_table_filename-seglinkedit-segprot-segs_read_only_addr-segs_read_write_addr-single_module-static-sub_library-sub_umbrella-twolevel_namespace-umbrella-undefined-unexported_symbols_list-weak_reference_mismatches-whatsloaded
These options get passed straight to the Darwin linker ๐ The Darwin linker man page has all the juicy details on each one, so go check there if you want the full tea ๐ต
๐ธ DEC Alpha Options ๐ธ
These -m options are made for DEC Alpha implementations, so they only show up for those chips โจ
-mno-soft-float,-msoft-floatโ This pair is the hardware floating-point toggle ๐ฅ-mno-soft-floatmeans use the hardware floating-point instructions, and-msoft-floatmeans don't. When-msoft-floatis on, the functions inlibgcc.ado the floating-point work. Unless they've been swapped out for routines that emulate those operations, or compiled to call those emulation routines, these routines still issue floating-point operations. If you're compiling for an Alpha with no floating-point operations, you have to make sure the library is built so it doesn't call them. Also, Alpha implementations without floating-point operations are required to have floating-point registers, so that part's non-negotiable ๐-mfp-reg,-mno-fp-regsโ-mfp-reggenerates code that uses the floating-point register set, and-mno-fp-regsgenerates code that doesn't.-mno-fp-regsimplies-msoft-float. If the floating-point register set isn't used, floating-point operands get passed in integer registers as if they were integers, and floating-point results come back in$0instead of$f0. This is a non-standard calling sequence, so any function with a floating-point argument or return value that gets called by code compiled with-mno-fp-regshas to be compiled with that option too. A typical use is building a kernel that doesn't use any floating-point registers, so it doesn't need to save and restore them ๐ง-mieeeโ The Alpha architecture has floating-point hardware that's tuned for maximum performance. It's mostly IEEE compliant, but full compliance needs some software help ๐ซถ This option generates fully IEEE-compliant code, except the inexact-flag isn't maintained (see below). When it's on, the preprocessor macro_IEEE_FPgets defined during compilation. The resulting code runs a bit slower, but it can properly handle denormalized numbers and exceptional IEEE values like not-a-number and plus/minus infinity. Other Alpha compilers call this option-ieee_with_no_inexact.
DEBIAN SPECIFIC: This option is on by default foralpha-linux-gnu, unless-ffinite-math-only(which is part of the-ffast-mathset) is specified. The reason is that the software functions in the GNU libc math libraries generate denormalized numbers, NaNs, and infs. All of those will cause a program toSIGFPEwhen it tries to use the results without-mieee. ๐ญ
-mieee-with-inexactโ This is like-mieee, except the generated code also maintains the IEEE inexact-flag, so it becomes fully-compliant IEEE math ๐ฅ On top of_IEEE_FP, the preprocessor macro_IEEE_FP_EXACTgets defined too. On some Alpha implementations this can run significantly slower than the default code. Very little code actually depends on the inexact-flag, so you should normally not specify this option. Other Alpha compilers call this option-ieee_with_inexact.-mfp-trap-mode=trap-modeโ This option controls which floating-point related traps are enabled. Other Alpha compilers call it-fptm trap-mode. The trap mode can be set to one of four values:nโ This is the default (normal) setting. The only traps enabled are the ones that can't be disabled in software, like the division by zero trap.uโ On top of everythingnenables, underflow traps are enabled too.suโ Likeu, but the instructions get marked as safe for software completion (see the Alpha architecture manual for details).suiโ Likesu, but inexact traps are enabled as well.
-mfp-rounding-mode=rounding-modeโ Selects the IEEE rounding mode ๐ Other Alpha compilers call it-fprm rounding-mode. Therounding-modecan be one of:nโ Normal IEEE rounding mode. Floating-point numbers get rounded towards the nearest machine number, or towards the even machine number in case of a tie.mโ Round towards minus infinity.cโ Chopped rounding mode. Floating-point numbers get rounded towards zero.dโ Dynamic rounding mode. A field in the floating-point control register (fpcr, see the Alpha architecture reference manual) controls which rounding mode is in effect. The C library initializes this register for rounding towards plus infinity, so unless your program changes thefpcr,dworks out to round towards plus infinity.
-mtrap-precision=trap-precisionโ Alpha floating-point traps are imprecise, which is a big deal ๐ฌ Without software help, you can't recover from a floating trap, and program execution normally has to be terminated. GCC can generate code that helps operating system trap handlers figure out the exact spot that caused a floating-point trap. Depending on what your application needs, you can pick one of these precision levels:pโ Program precision. This is the default, and it means a trap handler can only tell which program caused a floating-point exception.fโ Function precision. The trap handler can figure out which function caused a floating-point exception.iโ Instruction precision. The trap handler can figure out the exact instruction that caused a floating-point exception.
Other Alpha compilers offer the equivalent options -scope_safe and -resumption_safe.
-mieee-conformantโ This option marks the generated code as IEEE conformant ๐
You must not use this option unless you also specify-mtrap-precision=iand either-mfp-trap-mode=suor-mfp-trap-mode=sui. Its only effect is to emit the line.eflag 48in the function prologue of the generated assembly file.
-mbuild-constantsโ Normally GCC looks at a 32- or 64-bit integer constant to see if it can build it from smaller constants in two or three instructions. If it can't, it outputs the constant as a literal and generates code to load it from the data segment at run time ๐ง
Use this option to make GCC build all integer constants using code, even if that takes more instructions (the maximum is six). You typically use this option to build a shared library dynamic loader. Since the loader is itself a shared library, it has to relocate itself in memory before it can find the variables and constants in its own data segment.
-mbwx,-mno-bwx,-mcix,-mno-cix,-mfix,-mno-fix,-mmax,-mno-maxโ These tell GCC whether it should generate code that uses the optional BWX, CIX, FIX and MAX instruction sets ๐ The default is to use the instruction sets supported by the CPU type you specify via the-mcpu=option, or the CPU that GCC was built on if you don't specify one.-mfloat-vax,-mfloat-ieeeโ Generate code that uses (or doesn't use) VAX F and G floating-point arithmetic instead of IEEE single and double precision ๐ฆ-mexplicit-relocs,-mno-explicit-relocsโ Older Alpha assemblers had no way to generate symbol relocations except through assembler macros, and those macros don't allow optimal instruction scheduling. GNU binutils as of version 2.12 supports a new syntax that lets the compiler explicitly mark which relocations apply to which instructions. This option is mostly useful for debugging, since GCC detects the assembler's capabilities when it's built and sets the default accordingly ๐ธ-msmall-data,-mlarge-dataโ When-mexplicit-relocsis in effect, static data is accessed viagp-relative relocations. When-msmall-datais used, objects 8 bytes long or smaller are placed in a small data area (the".sdata"and".sbss"sections) and accessed via 16-bit relocations off of the$gpregister. This limits the small data area to 64KB, but lets the variables be accessed directly with a single instruction โจ
The default is -mlarge-data. With this option, the data area is limited to just below 2GB. Programs that need more than 2GB of data must use "malloc" or "mmap" to allocate that data in the heap instead of in the program's data segment.
When generating code for shared libraries, -fpic implies -msmall-data, and -fPIC implies -mlarge-data.
-msmall-text,-mlarge-textโ With-msmall-text, the compiler assumes the code of the entire program (or shared library) fits in 4MB, so it's reachable with a branch instruction ๐ When-msmall-datais used, the compiler can assume all local symbols share the same$gpvalue, which cuts the number of instructions needed for a function call from 4 to 1.
The default is -mlarge-text.
-mcpu=cpu_typeโ okay so this sets the instruction set and the scheduling vibes for machine typecpu_type๐. You can name it with the EV style name or the chip number. GCC has scheduling params for the EV4, EV5, and EV6 family, and it picks the instruction set defaults based on the processor you choose. If you don't pick a processor type, GCC just goes with whatever processor the compiler was built on ๐ง.
Supported values for cpu_type are:
ev4,ev45,21064โ schedules as an EV4 and has no instruction set extensions ๐ธev5,21164โ schedules as an EV5 and has no instruction set extensions ๐ธev56,21164aโ schedules as an EV5 and supports the BWX extension โจpca56,21164pc,21164PCโ schedules as an EV5 and supports the BWX and MAX extensions ๐ev6,21264โ schedules as an EV6 and supports the BWX, FIX, and MAX extensions ๐ฅev67,21264aโ schedules as an EV6 and supports the BWX, CIX, FIX, and MAX extensions ๐
Native toolchains also support the value native, which selects the best architecture option for the host processor. -mcpu=native has no effect if GCC does not recognize the processor ๐ฆ.
-mtune=cpu_typeโ this one is lowkey simpler. It only sets the instruction scheduling parameters for machine typecpu_type, and the instruction set stays exactly as it is ๐.
Native toolchains also support the value native, which selects the best architecture option for the host processor. -mtune=native has no effect if GCC does not recognize the processor ๐ซถ.
-mmemory-latency=timeโ sets the latency the scheduler should assume for typical memory references as the application sees them. ngl this number depends a LOT on the application's memory access patterns and the size of the external cache on the machine ๐.
Valid options for time are:
numberโ a decimal number representing clock cycles ๐L1,L2,L3,mainโ the compiler has estimates of clock cycles for "typical" EV4 & EV5 hardware at the Level 1, 2, and 3 caches (also called Dcache, Scache, and Bcache), plus main memory. Note thatL3is only valid for EV5 ๐.
โจ eBPF Options โจ
-mframe-limit=bytesโ this is the hard limit for frame sizes, in bytes ๐ง. Right now the value you pass should be less than or equal to32767. It defaults to whatever limit is imposed by the version of the Linux kernel being targeted ๐.-mkernel=versionโ this sets the minimum kernel version that will run your compiled program. GCC uses it to decide which instructions to use, which kernel helpers to allow, etc. ๐ง Right nowversioncan be one of4.0,4.1,4.2,4.3,4.4,4.5,4.6,4.7,4.8,4.9,4.10,4.11,4.12,4.13,4.14,4.15,4.16,4.17,4.18,4.19,4.20,5.0,5.1,5.2,latest, ornative๐ .-mbig-endianโ generate code for a big-endian target ๐ธ.-mlittle-endianโ generate code for a little-endian target. This is the default ๐.-mxbpfโ generates code for an expanded version of BPF that relaxes some of the restrictions the BPF architecture normally imposes ๐ฆ:-<Save and restore callee-saved registers at function entry and>exit, respectively.
โจ FR30 Options โจ
These options are defined specifically for the FR30 port ๐.
-msmall-modelโ uses the small address space model. This can produce smaller code, but it does assume that all symbolic values and addresses fit into a 20-bit range ๐.-mno-lsimโ assumes runtime support has already been provided, so there's no need to include the simulator library (libsim.a) on the linker command line ๐ซถ.
โจ FT32 Options โจ
These options are defined specifically for the FT32 port ๐.
-msimโ tells GCC the program will run on the simulator. This links in an alternate runtime startup and library ๐ง.
๐จ bestie, you must NOT use this option when generating programs that will run on real hardware! You have to provide your own runtime library for whatever I/O functions are needed instead ๐.
-mlraโ enables Local Register Allocation. It's still experimental for FT32, so by default the compiler uses standard reload ๐.-mnodivโ doesn't usedivandmodinstructions ๐.-mft32bโ enables use of the extended instructions of the FT32B processor โจ.-mcompressโ compresses all code using the Ft32B code compression scheme ๐ฆ.-mnopmโ doesn't generate code that reads program memory ๐ฅ.
โจ FRV Options โจ
-mgpr-32โ only uses the first 32 general-purpose registers ๐ .-mgpr-64โ uses all 64 general-purpose registers ๐.-mfpr-32โ uses only the first 32 floating-point registers ๐ธ.-mfpr-64โ uses all 64 floating-point registers โจ.-mhard-floatโ uses hardware instructions for floating-point operations ๐ฅ.-msoft-floatโ uses library routines for floating-point operations instead ๐ซถ.-malloc-ccโ dynamically allocates condition code registers ๐ง.-mfixed-ccโ doesn't try to dynamically allocate condition code registers. It only usesicc0andfcc0๐.-mdwordโ changes the ABI to use double word insns ๐.-mno-dwordโ doesn't use double word instructions ๐.-mdoubleโ uses floating-point double instructions ๐.-mno-doubleโ doesn't use floating-point double instructions ๐.-mmediaโ uses media instructions ๐ฆ.-mno-mediaโ doesn't use media instructions ๐ .-mmuladdโ uses multiply and add/subtract instructions ๐.-mno-muladdโ doesn't use multiply and add/subtract instructions ๐.-mfdpicโ selects the FDPIC ABI, which uses function descriptors to represent pointers to functions ๐ง . Without any PIC/PIE-related options, it implies-fPIE. With-fpicor-fpie, it assumes GOT entries and small data are within a 12-bit range from the GOT base address. With-fPICor-fPIE, GOT offsets are computed with 32 bits. With abfin-elftarget, this option implies-msim๐.-minline-pltโ enables inlining of PLT entries in function calls to functions that aren't known to bind locally ๐ฅ. It has no effect without-mfdpic. It's enabled by default if you're optimizing for speed and compiling for shared libraries (i.e.,-fPICor-fpic), or when an optimization option such as-O3or above is on the command line ๐.-mTLSโ assumes a large TLS segment when generating thread-local code ๐ธ.-mtlsโ does not assume a large TLS segment when generating thread-local code ๐ง.-mgprel-roโ enables the use of "GPREL" relocations in the FDPIC ABI for data that is known to be in read-only sections ๐. It's enabled by default, except for-fpicor-fpie. Even though it may help make the global offset table smaller, it trades 1 instruction for 4 there. With-fPICor-fPIE, it trades 3 instructions for 4, one of which may be shared by multiple symbols, and it avoids the need for a GOT entry for the referenced symbol, so it's more likely to be a win. If it isn't,-mno-gprel-rocan be used to disable it ๐ซถ.-multilib-library-picโ links with the (library, not FD) pic libraries. It's implied by-mlibrary-pic, as well as by-fPICand-fpicwithout-mfdpic. You should never have to use it explicitly ๐.-mlinked-fpโ follows the EABI requirement of always creating a frame pointer whenever a stack frame is allocated ๐ . This option is enabled by default and can be disabled with-mno-linked-fp๐ฆ.-mlong-callsโ uses indirect addressing to call functions outside the current compilation unit ๐. This lets the functions be placed anywhere within the 32-bit address space ๐.-malign-labelsโ tries to align labels to an 8-byte boundary by inserting NOPs into the previous packet ๐ง . This option only has an effect when VLIW packing is enabled. It doesn't create new packets; it just adds NOPs to existing ones ๐.-mlibrary-picโ generates position-independent EABI code ๐.-macc-4โ uses only the first four media accumulator registers ๐ธ.-macc-8โ uses all eight media accumulator registers โจ.-mpackโ packs VLIW instructions ๐ฅ.-mno-packโ does not pack VLIW instructions ๐.-mno-eflagsโ does not mark ABI switches ine_flags๐.-mcond-moveโ enables the use of conditional-move instructions. This is the default ๐.
โ ๏ธ This switch is mostly for debugging the compiler and will probably get removed in a future version, so don't build your whole life around it ๐.
-mno-cond-moveโ disables the use of conditional-move instructions ๐ง.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐.
-msccโ enables the use of conditional set instructions. This is the default ๐.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐ .
-mno-sccโ disables the use of conditional set instructions ๐.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐ฆ.
-mcond-execโ enables the use of conditional execution. This is the default ๐ฅ.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐ซถ.
-mno-cond-execโ disables the use of conditional execution ๐ธ.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐ง .
-mvliw-branchโ runs a pass to pack branches into VLIW instructions. This is the default โจ.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐.
-mno-vliw-branchโ does not run a pass to pack branches into VLIW instructions ๐.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐.
-mmulti-cond-execโ enables optimization of&&and||in conditional execution. This is the default ๐.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐.
-mno-multi-cond-execโ disables optimization of&&and||in conditional execution ๐.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐ .
-mnested-cond-execโ enables nested conditional execution optimizations. This is the default ๐.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐ฆ.
-mno-nested-cond-execโ disables nested conditional execution optimizations ๐ฅ.
โ ๏ธ Mostly for debugging the compiler, and it'll likely be removed in a future version ๐.
Okay so this one's mainly for debugging the compiler, and it'll likely get yeeted in a future version ๐ don't get too attached bestie.
-moptimize-membarโ This one's giving clean-up energy ๐งน It removes redundantmembarinstructions from the compiler-generated code. It's on by default, so you get the glow-up for free โจ-mno-optimize-membarโ Not feeling the auto clean-up? This turns off the automatic removal of redundantmembarinstructions from the generated code ๐ โโ๏ธ-mtomcat-statsโ Tells gas to print out tomcat statistics ๐-mcpu=cpuโ Pick the processor type you want code generated for ๐ป The possible values arefrv,fr550,tomcat,fr500,fr450,fr405,fr400,fr300andsimple. Choose your fighter ๐ซถ
๐ GNU/Linux Options ๐
These -m options are defined for GNU/Linux targets, so if you're on Linux, these are your people ๐ง
-mglibcโ Use the GNU C library ๐ This is the default except on*-*-linux-*uclibc*,*-*-linux-*musl*and*-*-linux-*android*targets, so don't stress if you're on one of those ๐-muclibcโ Use the uClibc C library. This is the default on*-*-linux-*uclibc*targets ๐ฆ-mmuslโ Use the musl C library. This is the default on*-*-linux-*musl*targets ๐ธ-mbionicโ Use the Bionic C library. This is the default on*-*-linux-*android*targets ๐ค-mandroidโ Compile code that's compatible with the Android platform ๐ฑ This is the default on*-*-linux-*android*targets, and it's very main character energy.
When compiling,-mandroidenables-mbionic,-fPIC,-fno-exceptionsand-fno-rttiby default. When linking, it makes the GCC driver pass Android-specific options to the linker. Finally, it causes the preprocessor macro__ANDROID__to be defined. Bestie, that's a lot of work for one flag ๐ญ
-tno-android-ccโ Disables the compilation effects of-mandroid, so-mbionic,-fPIC,-fno-exceptionsand-fno-rttiare not turned on by default ๐ โโ๏ธ-tno-android-ldโ Disables the linking effects of-mandroid, so the linker just gets standard Linux linking options instead ๐ง
๐ H8/300 Options ๐
These -m options are defined for the H8/300 implementations ๐ง
-mrelaxโ Shortens some address references at link time, when possible ๐ช It does this by using the linker option-relax.-mhโ Generate code for the H8/300H ๐-msโ Generate code for the H8S ๐-mnโ Generate code for the H8S and H8/300H in the normal mode. This one has to be used with either-mhor-ms๐ซถ-ms2600โ Generate code for the H8S/2600. This switch must be used with-ms๐-mexrโ Extended registers get stored on the stack before a function with the monitor attribute runs. This is the default option, and it's only valid for H8S targets ๐ง-mno-exrโ Extended registers do not get stored on the stack before a function with the monitor attribute runs. This is the default option for this one, and it's only valid for H8S targets ๐-mint32โ Makesintdata 32 bits by default ๐ฅ-malign-300โ On the H8/300H and H8S, this uses the same alignment rules as the H8/300 โจ The default for the H8/300H and H8S is to align longs and floats on 4-byte boundaries, but-malign-300moves them to 2-byte boundaries instead. This option has no effect on the H8/300 ๐
๐ฆ HPPA Options ๐ฆ
These -m options are defined for the HPPA family of computers, which is a whole vibe ๐ฅ๏ธ
-march=architecture-typeโ Generate code for the specified architecture ๐๏ธ The choices are1.0for PA 1.0,1.1for PA 1.1, and2.0for PA 2.0 processors. To figure out the right architecture option for your machine on an HP-UX system, check out/usr/lib/sched.models๐ Code compiled for lower numbered architectures runs on higher numbered architectures, but not the other way around, so keep that in mind ๐-mpa-risc-1-0,-mpa-risc-1-1,-mpa-risc-2-0โ These are synonyms for-march=1.0,-march=1.1, and-march=2.0respectively ๐ซถ-mcaller-copiesโ The caller copies function arguments that get passed by hidden reference ๐ซฃ This one should be used with care, because it's not compatible with the default 32-bit runtime. The good news is that only aggregates larger than eight bytes are passed by hidden reference, and this option gives you better compatibility with OpenMP ๐ธ-mjump-in-delayโ This option is ignored and only provided for compatibility purposes ๐คทโโ๏ธ-mdisable-fpregsโ Prevents floating-point registers from being used in any manner ๐ซ This is necessary for compiling kernels that do lazy context switching of floating-point registers. Heads up though: if you use this option and then try to do floating-point operations, the compiler aborts ๐-mdisable-indexingโ Stops the compiler from using indexing address modes ๐ โโ๏ธ This dodges some rather obscure problems when compiling MIG generated code under MACH ๐ง-mno-space-regsโ Generates code that assumes the target has no space registers ๐ This lets GCC generate faster indirect calls and use unscaled index address modes. Such code is suitable for level 0 PA systems and kernels ๐-mfast-indirect-callsโ Generates code that assumes calls never cross space boundaries, so GCC can emit code that does faster indirect calls ๐๏ธ
This option does not work in the presence of shared libraries or nested functions. Be careful, bestie ๐
-mfixed-range=register-rangeโ Generates code that treats the given register range as fixed registers, meaning the register allocator can't use them ๐ This is super useful when compiling kernel code. You specify a register range as two registers separated by a dash, and you can specify multiple ranges separated by a comma ๐งฉ-mlong-load-storeโ Generates 3-instruction load and store sequences, which are sometimes required by the HP-UX 10 linker ๐ This is equivalent to the+koption to the HP compilers ๐-mportable-runtimeโ Uses the portable calling conventions HP proposed for ELF systems ๐-mgasโ Enables the use of assembler directives that only GAS understands ๐ฃ-mschedule=cpu-typeโ Schedules code according to the constraints for the machine typecpu-type๐๏ธ The choices are700 7100,7100LC,7200,7300and8000. Same deal as before: check/usr/lib/sched.modelson an HP-UX system to find the proper scheduling option for your machine. The default scheduling is8000โจ-mlinker-optโ Enables the optimization pass in the HP-UX linker ๐ Heads up: this makes symbolic debugging impossible ๐ญ It also triggers a bug in the HP-UX 8 and HP-UX 9 linkers, where they give bogus error messages when linking some programs ๐ซ-msoft-floatโ Generates output containing library calls for floating point ๐งฎ
Warning, bestie: the requisite libraries are not available for all HPPA targets. Normally the facilities of the machine's usual C compiler are used, but that can't be done directly in cross-compilation. You'll need to make your own arrangements to provide suitable library functions for cross-compilation ๐จ
-msoft-float changes the calling convention in the output file, so it's only useful if you compile all of a program with this option. In particular, you need to compile libgcc.a, the library that comes with GCC, with -msoft-float for this to work ๐งต
-msioโ Generates the predefine_SIOfor server IO ๐ฅ๏ธ The default is-mwsio.-mwsiogenerates the predefines__hp9000s700,__hp9000s700__and_WSIOfor workstation IO. Both options are available under HP-UX and HI-UX ๐ป-mgnu-ldโ Uses options specific to GNU ld ๐ This passes-sharedto ld when building a shared library. It's the default when GCC is configured, explicitly or implicitly, with the GNU linker. This option doesn't change which ld gets called. It only changes what parameters get passed to that ld. The ld that gets called is determined by the--with-ldconfigure option, GCC's program search path, and finally the user'sPATH. You can print the linker GCC uses withwhichgcc -print-prog-name=ld``. This option is only available on the 64-bit HP-UX GCC, i.e. configured withhppa*64*-*-hpux*๐ซถ-mhp-ldโ Uses options specific to HP ld ๐งโ๐ป This passes-bto ld when building a shared library and passes+Accept TypeMismatchto ld on all links. It's the default when GCC is configured, explicitly or implicitly, with the HP linker. Just like-mgnu-ld, it doesn't affect which ld gets called, only the parameters. That's still determined by the--with-ldconfigure option, GCC's program search path, and finally the user'sPATH. You can print the linker used by GCC withwhichgcc -print-prog-name=ld``. This option is only available on the 64-bit HP-UX GCC, i.e. configured withhppa*64*-*-hpux*๐-mlong-callsโ Generates code that uses long call sequences ๐ This makes sure a call can always reach linker generated stubs. By default, long calls are only generated when the distance from the call site to the beginning of the function or translation unit (depending on the case) goes over a predefined limit set by the branch type being used. Those limits for normal calls are7,600,000and240,000bytes, respectively for the PA 2.0 and PA 1.X architectures. Sibcalls are always limited at240,000bytes ๐
Distances are measured from the beginning of functions when using -ffunction-sections, or when using -mgas and -mno-portable-runtime together under HP-UX with the SOM linker ๐งญ
It's normally not desirable to use this option because it degrades performance ๐ญ However, it may be useful in large applications, particularly when partial linking is used to build the application.
The types of long calls used depend on the capabilities of the assembler and linker, and the type of code being generated. The impact on systems that support long absolute calls, and long pic symbol-difference or pc-relative calls, should be relatively small. However, an indirect call is used on 32-bit ELF systems in pic code, and it is quite long ๐ข
-munix=unix-stdโ Generates compiler predefines and selects a startfile for the specified UNIX standard ๐ The choices forunix-stdare93,95and98.93is supported on all HP-UX versions.95is available on HP-UX 10.10 and later.98is available on HP-UX 11.11 and later. The default values are93for HP-UX 10.00,95for HP-UX 10.10 through 11.00, and98for HP-UX 11.11 and later ๐๏ธ-munix=93โ okay so this one gives you the exact same predefines as GCC 3.3 and 3.4 ๐-munix=95โ this one adds extra predefines forXOPEN_UNIXand_XOPEN_SOURCE_EXTENDED, plus the startfileunix95.o๐ฆ-munix=98โ this one adds even more predefines:_XOPEN_UNIX,_XOPEN_SOURCE_EXTENDED,_INCLUDE__STDC_A1_SOURCE, and_INCLUDE_XOPEN_SOURCE_500, plus the startfileunix98.o๐
โ ๏ธ bestie, this option changes the interfaces for a bunch of library routines, and it also messes with how the C library behaves. Use it with extreme care ๐ญ
Library code that's supposed to work with more than one UNIX standard has to test, set, and restore the variable __xpg4_extended_mask as needed. Most GNU software doesn't do this, so don't expect it everywhere ๐
-nolibdldโ stops the generation of link options that searchlibdld.slwhen-staticis used on HP-UX 10 and later ๐-staticโ the HP-UX version ofsetlocalein libc depends onlibdld.sl, and there's no archive version of it โจ So when you pass-static, you need special link options to sort that dependency out.
On HP-UX 10 and later, the GCC driver adds those necessary options for you when you use -static. This makes the resulting binary dynamic ๐ธ On the 64-bit port, the linkers make dynamic binaries by default anyway. If you don't want the driver adding these link options, use -nolibdld.
-threadsโ adds multithreading support with the dce thread library under HP-UX ๐งต It sets flags for both the preprocessor and the linker.
โจ IA-64 Options โจ
These are the -m options defined for the Intel IA-64 architecture ๐
-mbig-endianโ generates code for a big-endian target. This is the default for HP-UX ๐-mlittle-endianโ generates code for a little-endian target. This is the default for AIX5 and GNU/Linux ๐-mgnu-as,-mno-gnu-asโ generates (or doesn't generate) code for the GNU assembler. This is the default โจ-mgnu-ld,-mno-gnu-ldโ generates (or doesn't generate) code for the GNU linker. This is the default ๐-mno-picโ generates code that doesn't use a global pointer register ๐ โโ๏ธ The result isn't position independent code, and it violates the IA-64 ABI, so be careful ๐ฌ-mvolatile-asm-stop,-mno-volatile-asm-stopโ generates (or doesn't generate) a stop bit right before and after volatile asm statements ๐-mregister-names,-mno-register-namesโ generates (or doesn't generate)in,loc, andoutregister names for the stacked registers. This might make the assembler output easier to read ๐-mno-sdata,-msdataโ disables (or enables) optimizations that use the small data section. This can be handy for working around optimizer bugs ๐-mconstant-gpโ generates code that uses a single constant global pointer value. This is useful when compiling kernel code ๐ง-mauto-picโ generates code that's self-relocatable. This implies-mconstant-gp. It's useful when compiling firmware code ๐ซถ-minline-float-divide-min-latencyโ generates code for inline divides of floating-point values using the minimum latency algorithm ๐ฅ-minline-float-divide-max-throughputโ generates code for inline divides of floating-point values using the maximum throughput algorithm ๐ฅ-mno-inline-float-divideโ doesn't generate inline code for divides of floating-point values ๐-minline-int-divide-min-latencyโ generates code for inline divides of integer values using the minimum latency algorithm โญ-minline-int-divide-max-throughputโ generates code for inline divides of integer values using the maximum throughput algorithm โญ-mno-inline-int-divideโ doesn't generate inline code for divides of integer values ๐-minline-sqrt-min-latencyโ generates code for inline square roots using the minimum latency algorithm ๐ธ-minline-sqrt-max-throughputโ generates code for inline square roots using the maximum throughput algorithm ๐ธ-mno-inline-sqrtโ doesn't generate inline code forsqrt๐-mfused-madd,-mno-fused-maddโ does (or doesn't) generate code that uses the fused multiply/add or multiply/subtract instructions. The default is to use these instructions ๐-mno-dwarf2-asm,-mdwarf2-asmโ doesn't (or does) generate assembler code for the DWARF line number debugging info. This might be useful when you're not using the GNU assembler ๐ฆ-mearly-stop-bits,-mno-early-stop-bitsโ allows stop bits to be placed earlier than immediately before the instruction that triggered the stop bit. This can improve instruction scheduling, but it doesn't always ๐คทโโ๏ธ-mfixed-range=register-rangeโ generates code that treats the given register range as fixed registers. A fixed register is one the register allocator can't use. This is useful when compiling kernel code ๐ง A register range is written as two registers separated by a dash, and you can give multiple ranges separated by a comma.-mtls-size=tls-sizeโ specifies the bit size of immediate TLS offsets. The valid values are14,22, and64๐-mtune=cpu-typeโ tunes the instruction scheduling for a particular CPU. The valid values areitanium,itanium1,merced,itanium2, andmckinley๐-milp32,-mlp64โ generates code for a 32-bit or 64-bit environment. The 32-bit environment setsint,long, and pointer to 32 bits. The 64-bit environment setsintto 32 bits andlongand pointer to 64 bits. These are HP-UX specific flags ๐-mno-sched-br-data-spec,-msched-br-data-specโ (dis/en)ables data speculative scheduling before reload. This results in generation ofld.ainstructions and the matching check instructions (ld.c/chk.a). The default setting is disabled ๐-msched-ar-data-spec,-mno-sched-ar-data-specโ (en/dis)ables data speculative scheduling after reload. This results in generation ofld.ainstructions and the matching check instructions (ld.c/chk.a). The default setting is enabled ๐-mno-sched-control-spec,-msched-control-specโ (dis/en)ables control speculative scheduling. This feature is only available during region scheduling (that is, before reload). It results in generation of theld.sinstructions and the matching check instructionschk.s. The default setting is disabled ๐-msched-br-in-data-spec,-mno-sched-br-in-data-specโ (en/dis)ables speculative scheduling of instructions that depend on the data speculative loads before reload. This only works if-msched-br-data-specis enabled. The default setting is enabled ๐-msched-ar-in-data-spec,-mno-sched-ar-in-data-specโ (en/dis)ables speculative scheduling of instructions that depend on the data speculative loads after reload. This only works if-msched-ar-data-specis enabled. The default setting is enabled ๐-msched-in-control-spec,-mno-sched-in-control-specโ (en/dis)ables speculative scheduling of instructions that depend on the control speculative loads. This only works if-msched-control-specis enabled. The default setting is enabled ๐-mno-sched-prefer-non-data-spec-insns,-msched-prefer-non-data-spec-insnsโ if enabled, data-speculative instructions only get picked for scheduling when there are no other choices at the moment. This makes data speculation much more conservative. The default setting is disabled ๐ซง-mno-sched-prefer-non-control-spec-insns,-msched-prefer-non-control-spec-insnsโ if enabled, control-speculative instructions only get picked for scheduling when there are no other choices at the moment. This makes control speculation much more conservative. The default setting is disabled ๐ซง-mno-sched-count-spec-in-critical-path,-msched-count-spec-in-critical-pathโ if enabled, speculative dependencies get considered when computing instruction priorities. This makes speculation a bit more conservative. The default setting is disabled ๐ซง-msched-spec-ldcโ uses a simple data speculation check. This option is on by default โ-msched-control-spec-ldcโ uses a simple check for control speculation. This option is on by default โ-msched-stop-bits-after-every-cycleโ places a stop bit after every cycle when scheduling. This option is on by default โ-msched-fp-mem-deps-zero-costโ assumes that floating-point stores and loads aren't likely to conflict when placed into the same instruction group. This option is disabled by default ๐ โโ๏ธ-msel-sched-dont-check-control-specโ generates checks for control speculation in selective scheduling. This flag is disabled by default ๐ โโ๏ธ-msched-max-memory-insns=max-insnsโ sets a limit on the number of memory insns per instruction group, giving lower priority to later memory insns that try to schedule in the same group. This is often handy for preventing cache bank conflicts. The default value is1๐ง-msched-max-memory-insns-hard-limitโ makes the limit set bymsched-max-memory-insnsa hard limit, so no more than that number of memory insns can go in an instruction group. Otherwise the limit is "soft," which means non-memory operations get preferred once the limit is reached, but memory operations can still get scheduled ๐ง
๐ธ LM32 Options ๐ธ
These -m options are defined for the LatticeMico32 architecture ๐ท
-mbarrel-shift-enabledโ enables barrel-shift instructions ๐ซ-mdivide-enabledโ enables divide and modulus instructions ๐ซ-mmultiply-enabledโ enables multiply instructions ๐ซ-msign-extend-enabledโ enables sign extend instructions ๐ซ-muser-enabledโ enables user-defined instructions ๐ซ
๐ฆ M32C Options ๐ฆ
-mcpu=nameโ selects the CPU that code gets generated for.namecan ber8cfor the R8C/Tiny series,m16cfor the M16C (up to /60) series,m32cmfor the M16C/80 series, orm32cfor the M32C/80 series ๐-msimโ says the program will run on the simulator. This links in an alternate runtime library that supports things like file I/O ๐งช
๐จ never use this option when you're generating programs that will run on real hardware! You have to provide your own runtime library for whatever I/O functions you need.
-memregs=number: okay so this one sets how many memory-based pseudo-registers GCC uses during code generation ๐พ. They get treated like real registers, which makes it a tradeoff: GCC can squeeze your code into the registers it has, but leaning on memory instead of actual registers costs performance ๐ญ. Every module in a program has to be compiled with the samenumber, so you must not use this option with GCC's default runtime libraries ๐ซ.
๐ M32R/D Options ๐
These -m options are defined for Renesas M32R/D architectures ๐ธ
-m32r2: generate code for the M32R/2 ๐ฆ-m32rx: generate code for the M32R/X โจ-m32r: generate code for the M32R. This is the default ๐-mmodel=small: GCC assumes all objects live in the lower 16MB of memory, so their addresses can be loaded with theld24instruction, and that all subroutines are reachable with theblinstruction. This is the default ๐
The addressability of a particular object can be set with the model attribute ๐
.
-mmodel=medium: GCC assumes objects can be anywhere in the 32-bit address space, so it generatesseth/add3instructions to load their addresses, and assumes all subroutines are reachable with theblinstruction ๐.-mmodel=large: GCC assumes objects can be anywhere in the 32-bit address space (generatingseth/add3instructions to load their addresses), and assumes subroutines might not be reachable with theblinstruction. This means it generates the much slowerseth/add3/jlinstruction sequence ๐ข.-msdata=none: disables the small data area. Variables go into one of.data,.bss, or.rodata(unless thesectionattribute has been specified). This is the default ๐.
The small data area consists of the sections .sdata and .sbss. Objects can be explicitly put in the small data area with the section attribute using one of these sections ๐ง.
-msdata=sdata: puts small global and static data in the small data area, but does not generate special code to reference them ๐.-msdata=use: puts small global and static data in the small data area, and generates special instructions to reference them ๐ฅ.-G num: puts global and static objects less than or equal tonumbytes into the small data or BSS sections instead of the normal data or BSS sections. The default value ofnumis 8. The-msdataoption must be set to one ofsdataorusefor this to have any effect ๐ซถ.
All modules should be compiled with the same -G num value. Compiling with different values of num may or may not work. If it doesn't, the linker gives an error message. Incorrect code is not generated, though ๐.
-mdebug: makes the M32R-specific code in the compiler display some statistics that might help you debug your programs ๐.-malign-loops: aligns all loops to a 32-byte boundary ๐.-mno-align-loops: does not enforce a 32-byte alignment for loops. This is the default ๐ .-missue-rate=number: issuesnumberinstructions per cycle.numbercan only be 1 or 2 โก.-mbranch-cost=number:numbercan only be 1 or 2. If it's 1, branches are preferred over conditional code. If it's 2, the opposite applies ๐ฆ.-mflush-trap=number: specifies the trap number to use to flush the cache. The default is 12, and valid numbers are between 0 and 15 inclusive ๐ธ.-mno-flush-trap: specifies that the cache cannot be flushed by using a trap ๐ซ.-mflush-func=name: specifies the name of the operating system function to call to flush the cache. The default is_flush_cache, but a function call is only used if a trap is not available ๐ ๏ธ.-mno-flush-func: indicates that there is no OS function for flushing the cache ๐ โโ๏ธ.
๐ M680x0 Options ๐
These are the -m options defined for M680x0 and ColdFire processors. The default settings depend on which architecture was selected when the compiler was configured, so the defaults for the most common choices are given below ๐.
-march=arch: generates code for a specific M680x0 or ColdFire instruction set architecture. Permissible values ofarchfor M680x0 architectures are68000,68010,68020,68030,68040,68060andcpu32. ColdFire architectures are selected according to Freescale's ISA classification, and the permissible values areisaa,isaaplus,isabandisac๐ง .
GCC defines the macro __mcfarch__ whenever it's generating code for a ColdFire target. The arch in this macro is one of the -march arguments given above ๐.
When used together, -march and -mtune select code that runs on a family of similar processors but is optimized for a particular microarchitecture โจ.
-mcpu=cpu: generates code for a specific M680x0 or ColdFire processor. The M680x0 cpus are68000,68010,68020,68030,68040,68060,68302,68332andcpu32. Here's the ColdFire table, which also sorts the CPUs into families ๐ง:
Family : -mcpu arguments
51 : 51 51ac 51ag 51cn 51em 51je 51jf 51jg 51jm 51mm 51qe 51qm
5206 : 5202 5204 5206
5206e : 5206e
5208 : 5207 5208
5211a : 5210a 5211a
5213 : 5211 5212 5213
5216 : 5214 5216
52235 : 52230 52231 52232 52233 52234 52235
5225 : 5224 5225
52259 : 52252 52254 52255 52256 52258 52259
5235 : 5232 5233 5234 5235 523x
5249 : 5249
5250 : 5250
5271 : 5270 5271
5272 : 5272
5275 : 5274 5275
5282 : 5280 5281 5282 528x
53017 : 53011 53012 53013 53014 53015 53016 53017
5307 : 5307
5329 : 5327 5328 5329 532x
5373 : 5372 5373 537x
5407 : 5407
5475 : 5470 5471 5472 5473 5474 5475 547x 5480 5481 5482 5483 5484
5485
-mcpu=cpu overrides -march=arch if arch is compatible with cpu. Other combinations of -mcpu and -march are rejected ๐ซ.
GCC defines the macro __mcf_cpu_cpu when a ColdFire target cpu is selected. It also defines __mcf_family_family, where the value of family is given by the table above ๐.
-mtune=tune: tunes the code for a particular microarchitecture within the constraints set by-marchand-mcpu. The M680x0 microarchitectures are68000,68010,68020,68030,68040,68060andcpu32. The ColdFire microarchitectures arecfv1,cfv2,cfv3,cfv4andcfv4e๐ฆ.
You can also use -mtune=68020-40 for code that needs to run relatively well on 68020, 68030 and 68040 targets. -mtune=68020-60 is similar but includes 68060 targets as well. These two options select the same tuning decisions as -m68020-40 and -m68020-60 respectively ๐ธ.
GCC defines the macros __mcarch and __mcarch__ when tuning for 680x0 architecture arch. It also defines mcarch unless either -ansi or a non-GNU -std option is used. If GCC is tuning for a range of architectures, as selected by -mtune=68020-40 or -mtune=68020-60, it defines the macros for every architecture in the range ๐ง.
GCC also defines the macro __muarch__ when tuning for ColdFire microarchitecture uarch, where uarch is one of the arguments given above โจ.
-m68000,-mc68000: generates output for a 68000. This is the default when the compiler is configured for 68000-based systems, and it's equivalent to-march=68000๐ .
Use this option for microcontrollers with a 68000 or EC000 core, including the 68008, 68302, 68306, 68307, 68322, 68328 and 68356 ๐ซถ.
-m68010: generates output for a 68010. This is the default when the compiler is configured for 68010-based systems, and it's equivalent to-march=68010๐.-m68020,-mc68020: generates output for a 68020. This is the default when the compiler is configured for 68020-based systems, and it's equivalent to-march=68020๐.-m68030: generates output for a 68030. This is the default when the compiler is configured for 68030-based systems, and it's equivalent to-march=68030๐.-m68040: generates output for a 68040. This is the default when the compiler is configured for 68040-based systems, and it's equivalent to-march=68040๐.
This option inhibits the use of 68881/68882 instructions that have to be emulated by software on the 68040. Use it if your 68040 doesn't have code to emulate those instructions ๐.
-m68060: generates output for a 68060. This is the default when the compiler is configured for 68060-based systems, and it's equivalent to-march=68060๐ฅ.
This option inhibits the use of 68020 and 68881/68882 instructions that have to be emulated by software on the 68060. Use it if your 68060 doesn't have code to emulate those instructions ๐ซถ.
-mcpu32: generates output for a CPU32. This is the default when the compiler is configured for CPU32-based systems, and it's equivalent to-march=cpu32๐ง .
Use this option for microcontrollers with a CPU32 or CPU32+ core, including the 68330, 68331, 68332, 68333, 68334, 68336, 68340, 68341, 68349 and 68360 ๐.
-m5200: generates output for a 520X ColdFire CPU. This is the default when the compiler is configured for 520X-based systems. It's equivalent to-mcpu=5206, and is deprecated in favor of that option ๐ง.
Use this option for microcontroller with a 5200 core, including the MCF5202, MCF5203, MCF5204 and MCF5206 โจ.
-m5206e: generates output for a 5206e ColdFire CPU. The option is deprecated in favor of the equivalent-mcpu=5206e๐ง.-m528x: generates output for a member of the ColdFire 528X family. The option is deprecated in favor of the equivalent-mcpu=528x๐ง.-m5307: generates output for a ColdFire 5307 CPU. The option is deprecated in favor of the equivalent-mcpu=5307๐ง.-m5407: generates output for a ColdFire 5407 CPU. The option is deprecated in favor of the equivalent-mcpu=5407๐ง.-mcfv4e: generates output for a ColdFire V4e family CPU (e.g. 547x/548x). This includes the use of hardware floating-point instructions. It's equivalent to-mcpu=547x, and is deprecated in favor of that option ๐.-m68020-40: generates output for a 68040, without using any of the new instructions. This results in code that can run relatively efficiently on a 68020/68881, a 68030, or a 68040. The generated code does use the 68881 instructions that are emulated on the 68040 ๐ฆ.
Bestie, this one's basically the same as -march=68020 -mtune=68020-40 ๐
-m68020-60โ Okay, this one generates code for a 68060 but skips all the shiny new instructions ๐ . The result runs pretty efficiently on a 68020/68881, a 68030, or a 68040. The generated code does use the 68881 instructions, which the 68060 emulates ๐ฆ- The option is equivalent to
-march=68020 -mtune=68020-60.
- The option is equivalent to
-mhard-float,-m68881โ Turns on floating-point instructions โจ This is the default for 68020 and up, and for ColdFire devices that have an FPU. It defines the macro__HAVE_68881__on M680x0 targets and__mcffpu__on ColdFire targets.-msoft-floatโ No floating-point instructions here, just library calls instead ๐ซถ This is the default for 68000, 68010, and 68832 targets, and also for ColdFire devices with no FPU.-mdiv,-mno-divโ Generate (or don't generate) ColdFire hardware divide and remainder instructions ๐งฎ If-marchis used without-mcpu, the default is "on" for ColdFire architectures and "off" for M680x0 architectures. Otherwise, the default comes from the target CPU (either the default CPU, or the one specified by-mcpu). For example, the default is "off" for-mcpu=5206and "on" for-mcpu=5206e.- GCC defines the macro
__mcfhwdiv__when this option is enabled.
- GCC defines the macro
-mshortโ Treatsintas 16 bits wide, just likeshort int๐ Parameters passed on the stack also get aligned to a 16-bit boundary, even on targets whose API mandates promotion to 32-bit.-mno-shortโ Don't treatintas 16 bits wide. This is the default ๐-mnobitfield,-mno-bitfieldโ Skip the bit-field instructions.-m68000,-mcpu32and-m5200imply-mnobitfield.-mbitfieldโ Use the bit-field instructions.-m68020implies-mbitfield, and this is the default if you're using a configuration designed for a 68020 ๐-mrtdโ Okay, this one swaps in a totally different function-calling convention ๐ Functions that take a fixed number of arguments return with thertdinstruction, which pops their arguments while returning. That saves one instruction in the caller, since there's no need to pop the arguments there.- This calling convention is incompatible with the one normally used on Unix, so you can't use it if you need to call libraries compiled with the Unix compiler ๐
- You must provide function prototypes for all functions that take variable numbers of arguments (including
printf). Otherwise, incorrect code gets generated for calls to those functions. - Seriously incorrect code results if you call a function with too many arguments ๐ (Normally, extra arguments are harmlessly ignored.)
- The
rtdinstruction is supported by the 68010, 68020, 68030, 68040, 68060 and CPU32 processors, but not by the 68000 or 5200. - The default is
-mno-rtd.
-malign-int,-mno-align-intโ Controls whether GCC alignsint,long,long long,float,double, andlong doublevariables on a 32-bit boundary (-malign-int) or a 16-bit boundary (-mno-align-int) ๐ Aligning on 32-bit boundaries makes code run somewhat faster on processors with 32-bit busses, but it costs more memory.
โ ๏ธ Warning: if you use the -malign-int switch, GCC aligns structures containing the above types differently than most published application binary interface specifications for the m68k. Heads up, bestie ๐ซถ
Use the pc-relative addressing mode of the 68000 directly, instead of using a global offset table ๐งญ At present, this option implies -fpic, allowing at most a 16-bit offset for pc-relative addressing. -fPIC is not presently supported with -mpcrel, though this could be supported for 68020 and higher processors.
-mno-strict-align,-mstrict-alignโ-mno-strict-alignmeans do not assume unaligned memory references are handled by the system, and-mstrict-alignmeans do assume it ๐-msep-dataโ Generate code that lets the data segment live in a different area of memory from the text segment ๐ง This allows execute-in-place in an environment without virtual memory management. This option implies-fPIC.-mno-sep-dataโ Generate code that assumes the data segment follows the text segment. This is the default.-mid-shared-libraryโ Generate code that supports shared libraries via the library ID method ๐ฆ This allows execute-in-place and shared libraries in an environment without virtual memory management. This option implies-fPIC.-mno-id-shared-libraryโ Generate code that doesn't assume ID-based shared libraries are being used. This is the default.-mshared-library-id=nโ Specifies the identification number of the ID-based shared library being compiled ๐ข Specifying a value of 0 generates more compact code. Other values force the allocation of that number to the current library, but that's no more space- or time-efficient than omitting this option.-mxgot,-mno-xgotโ When generating position-independent code for ColdFire, this generates code that works if the GOT has more than 8192 entries ๐ข It's larger and slower than code generated without this option. On M680x0 processors you don't need this option, since-fPICis enough.- GCC normally uses a single instruction to load values from the GOT. It's relatively efficient, but it only works if the GOT is smaller than about 64k. Anything larger makes the linker report an error like this:
relocation truncated to fit: R_68K_GOT16O foobar
- If this happens, recompile your code with
-mxgot. It should then work with very large GOTs. However, code generated with-mxgotis less efficient, since it takes 4 instructions to fetch the value of a global symbol. - Some linkers, including newer versions of the GNU linker, can create multiple GOTs and sort GOT entries. If you have one of those linkers, you should only need
-mxgotwhen compiling a single object file that accesses more than 8192 GOT entries. Very few do. - These options have no effect unless GCC is generating position-independent code.
-mlong-jump-table-offsetsโ Uses 32-bit offsets inswitchtables. The default is 16-bit offsets.
๐ธ MCore Options ๐ธ
These are the -m options defined for the Motorola M*Core processors ๐
-mhardlit,-mno-hardlitโ Inline constants into the code stream if it can be done in two instructions or less โจ-mdiv,-mno-divโ Use the divide instruction. (Enabled by default.) ๐ฅ-mrelax-immediate,-mno-relax-immediateโ Allow arbitrary-sized immediates in bit operations.-mwide-bitfields,-mno-wide-bitfieldsโ Always treat bit-fields asint-sized.-m4byte-functions,-mno-4byte-functionsโ Force all functions to be aligned to a 4-byte boundary.-mcallgraph-data,-mno-callgraph-dataโ Emit callgraph information ๐-mslow-bytes,-mno-slow-bytesโ Prefer word access when reading byte quantities.-mlittle-endian,-mbig-endianโ Generate code for a little-endian target.-m210,-m340โ Generate code for the 210 processor.-mno-lsimโ Assume runtime support has already been provided, so leave the simulator library (libsim.a) off the linker command line ๐-mstack-increment=sizeโ Sets the maximum amount for a single stack increment operation ๐ Large values can speed up programs with functions that need a lot of stack space, but they can also trigger a segmentation fault if the stack gets extended too much. The default value is0x1000.
๐ง MeP Options ๐ง
-mabsdiffโ Enables theabsinstruction, which gives the absolute difference between two registers ๐-mall-optsโ Turns on every optional instruction: average, multiply, divide, bit operations, leading zero, absolute difference, min/max, clip, and saturation ๐-maverageโ Enables theaveinstruction, which computes the average of two registers.-mbased=nโ Variables of size n bytes or smaller get placed in the.basedsection by default ๐ Based variables use the$tpregister as a base register, and there's a 128-byte limit to the.basedsection.-mbitopsโ Enables the bit operation instructions: bit test (btstm), set (bsetm), clear (bclrm), invert (bnotm), and test-and-set (tas) ๐ฆ-mc=nameโ Picks which section constant data gets placed in.namemay betiny,near, orfar.-mclipโ Enables theclipinstruction. Note that-mclipisn't useful unless you also provide-mminmax๐ซถ-mconfig=nameโ Selects one of the built-in core configurations โญ Each MeP chip has one or more modules, and each module has a core CPU and a variety of coprocessors, optional instructions, and peripherals. TheMeP-Integratortool, which is not part of GCC, provides these configurations through this option. Using this option is the same as using all the corresponding command-line options. The default configuration isdefault.-mcopโ Enables the coprocessor instructions. By default this is a 32-bit coprocessor. Note that the coprocessor is normally enabled via the-mconfig=option.-mcop32โ Enables the 32-bit coprocessor's instructions.-mcop64โ Enables the 64-bit coprocessor's instructions.-mivc2โ Enables IVC2 scheduling. IVC2 is a 64-bit VLIW coprocessor ๐ฅ-mdcโ Causes constant variables to be placed in the.nearsection.-mdivโ Enables thedivanddivuinstructions.-mebโ Generate big-endian code.-melโ Generate little-endian code.-mio-volatileโ Tells the compiler that any variable marked with theioattribute is to be considered volatile ๐-mlโ Causes variables to be assigned to the.farsection by default.-mleadzโ Enables theleadz(leading zero) instruction.-mmโ Causes variables to be assigned to the.nearsection by default.-mminmaxโ Enables theminandmaxinstructions.-mmultโ Enables the multiplication and multiply-accumulate instructions.-mno-optsโ Disables all the optional instructions enabled by-mall-opts๐-mrepeatโ Enables therepeatanderepeatinstructions, which are used for low-overhead looping ๐-msโ okay so this one makes every variable default to the.tinysection ๐ง Heads up, that section has a 65536-byte limit ๐ and accesses to these variables use the%gpbase register ๐-msaturโ turns on the saturation instructions โจ ngl the compiler doesn't actually generate these itself yet, but the flag is here for compatibility with other tools, likeas๐ซถ-msdramโ links the SDRAM-based runtime instead of the default ROM-based runtime ๐งธ-msimโ links the simulator run-time libraries ๐ฅ๏ธ-msimnovecโ links the simulator runtime libraries, but leaves out the built-in support for reset and exception vectors and tables ๐-mtfโ makes all functions default to the.farsection ๐ฆ Without this one, functions default to.near-mtiny=nโ variables that arenbytes or smaller get put in the.tinysection, and they use the$gpbase register ๐ The default is4, but remember the.tinysection has that 65536-byte limit too ๐ญ
๐ธ MicroBlaze Options ๐ธ
-msoft-floatโ software emulation for floating point, and this is the default ๐-mhard-floatโ uses hardware floating-point instructions ๐ฅ-mmemcpyโ don't optimize block moves, just usememcpy๐-mno-clearbssโ deprecated ๐ use-fno-zero-initialized-in-bssinstead-mcpu=cpu-typeโ uses the features of, and schedules code for, the CPU you pick ๐ Supported values follow the formatvX.YY.Z, whereXis a major version,YYis the minor version, andZis compatibility code ๐ง Example values arev3.00.a,v4.00.b,v5.00.a,v5.00.b, andv6.00.aโจ-mxl-soft-mulโ software multiply emulation, the default ๐ง-mxl-soft-divโ software emulation for divides, also the default-mxl-barrel-shiftโ uses the hardware barrel shifter ๐๏ธ-mxl-pattern-compareโ uses pattern compare instructions ๐-msmall-dividesโ uses table lookup optimization for small signed integer divisions ๐งฎ-mxl-stack-checkโ deprecated, bestie ๐ use-fstack-checkinstead-mxl-gp-optโ uses GP-relative".sdata"/".sbss"sections ๐-mxl-multiply-highโ uses multiply high instructions for the high part of a 32x32 multiply ๐ช-mxl-float-convertโ uses hardware floating-point conversion instructions ๐-mxl-float-sqrtโ uses the hardware floating-point square root instruction โญ-mbig-endianโ generates code for a big-endian target ๐-mlittle-endianโ generates code for a little-endian target ๐-mxl-reorderโ uses reorder instructions (swap and byte reversed load/store) ๐-mxl-mode-app-modelโ selects the application modelapp-model๐ซง The valid models are:executableโ normal executable (default), uses the startup codecrt0.o-mpic-data-is-text-relativeโ assumes the displacement between the text and data segments is fixed at static link time ๐งท This lets data get referenced by offset from the start of the text address instead of the GOT, since PC-relative addressing isn't supportedxmdstubโ for use with the Xilinx Microprocessor Debugger (XMD) based software intrusive debug agent called xmdstub ๐ This one uses the startup filecrt1.oand sets the start address of the program to0x800bootstrapโ for applications that get loaded by a bootloader ๐ฅพ This model uses the startup filecrt2.o, which doesn't contain a processor reset vector handler, so it's perfect for handing control back to the bootloader on a processor reset instead of the applicationnovectorsโ for applications that don't need any of the MicroBlaze vectors ๐ โโ๏ธ This can be handy inside a monitoring application, and it usescrt3.oas its startup file
Option -xl-mode-app-model is a deprecated alias for -mxl-mode-app-model.
๐ฆ MIPS Options ๐ฆ
-EBโ generates big-endian code ๐-ELโ generates little-endian code ๐ This is the default formips*el-*-*configurations-march=archโ generates code that runs onarch, which can be the name of a generic MIPS ISA or the name of a particular processor โจ The ISA names aremips1, mips2, mips3, mips4, mips32, mips32r2, mips32r3, mips32r5, mips32r6, mips64, mips64r2, mips64r3, mips64r5andmips64r6. The processor names are4kc, 4km, 4kp, 4ksc, 4kec, 4kem, 4kep, 4ksd, 5kc, 5kf, 20kc, 24kc, 24kf2_1, 24kf1_1, 24kec, 24kef2_1, 24kef1_1, 34kc, 34kf2_1, 34kf1_1, 34kn, 74kc, 74kf2_1, 74kf1_1, 74kf3_2, 1004kc, 1004kf2_1, 1004kf1_1, i6400, i6500, interaptiv, loongson2e, loongson2f, loongson3a, gs464, gs464e, gs264e, m4k, m14k, m14kc, m14ke, m14kec, m5100, m5101, octeon, octeon+, octeon2, octeon3, orion, p5600, p6600, r2000, r3000, r3900, r4000, r4400, r4600, r4650, r4700, r5900, r6000, r8000, rm7000, rm9000, r10000, r12000, r14000, r16000, sb1, sr71000, vr4100, vr4111, vr4120, vr4130, vr4300, vr5000, vr5400, vr5500, xlrandxlp.- The special value
from-abipicks the most compatible architecture for the selected ABI, which ismips1for 32-bit ABIs andmips3for 64-bit ABIs ๐งฉ - The native Linux/GNU toolchain also supports the value
native, which picks the best architecture option for the host processor ๐ฅ๏ธ-march=nativehas no effect if GCC doesn't recognize the processor ๐ - In processor names, a final
000can be abbreviated ask(for example,-march=r2k) ๐ช Prefixes are optional, andvrmay be writtenr - Names of the form
nf2_1refer to processors with FPUs clocked at half the rate of the core, names of the formnf1_1refer to processors with FPUs clocked at the same rate as the core, and names of the formnf3_2refer to processors with FPUs clocked at a 3:2 ratio with respect to the core โฑ๏ธ For compatibility reasons,nfis accepted as a synonym fornf2_1, whilenxandbfxare accepted as synonyms fornf1_1 - GCC defines two macros based on this option ๐ง The first is
"_MIPS_ARCH", which gives the name of the target architecture as a string. The second has the form"_MIPS_ARCH_foo", wherefoois the capitalized value of"_MIPS_ARCH". For example,-march=r2000sets"_MIPS_ARCH"to"r2000"and defines the macro"_MIPS_ARCH_R2000" - The
"_MIPS_ARCH"macro uses the processor names listed above, so it has the full prefix and doesn't abbreviate000ask๐ Forfrom-abi, the macro names the resolved architecture (either"mips1"or"mips3"). It names the default architecture when no-marchoption is given
- The special value
-mtune=archโ optimizes forarch๐ฏ Among other things, this one controls the way instructions get scheduled and the perceived cost of arithmetic operations. The list ofarchvalues is the same as for-march- When this option isn't used, GCC optimizes for the processor specified by
-march๐ก By using-marchand-mtunetogether, you can generate code that runs on a whole family of processors, but optimize it for one particular member of that family ๐ฏ -mtunedefines the macros"_MIPS_TUNE"and"_MIPS_TUNE_foo", which work the same way as the-marchones described above
- When this option isn't used, GCC optimizes for the processor specified by
-mips1โ equivalent to-march=mips1๐-mips2โ equivalent to-march=mips2๐-mips3โ equivalent to-march=mips3๐-mips4โ equivalent to-march=mips4๐-mips32โ equivalent to-march=mips32๐-mips32r3โ equivalent to-march=mips32r3๐-mips32r5โ equivalent to-march=mips32r5๐-mips32r6โ equivalent to-march=mips32r6๐-mips64โ equivalent to-march=mips64๐-mips64r2โ equivalent to-march=mips64r2๐-mips64r3โ equivalent to-march=mips64r3๐-mips64r5โ equivalent to-march=mips64r5๐-mips64r6โ equivalent to-march=mips64r6๐-mips16,-mno-mips16โ generates (or doesn't generate) MIPS16 code ๐ง If GCC is targeting a MIPS32 or MIPS64 architecture, it uses the MIPS16e ASE. You can also control MIPS16 code generation on a per-function basis with themips16andnomips16attributes-mflip-mips16โ generates MIPS16 code on alternating functions ๐ข This one exists for regression testing of mixed MIPS16/non-MIPS16 code generation, so it's not meant for ordinary use when compiling your own code ๐ซ-minterlink-compressed,-mno-interlink-compressedโ requires (or doesn't require) that code using the standard (uncompressed) MIPS ISA be link-compatible with MIPS16 and microMIPS code, and vice versa ๐ For example, code using the standard ISA encoding can't jump directly to MIPS16 or microMIPS code, so it has to use a call or an indirect jump.-minterlink-compressedtherefore disables direct jumps unless GCC knows the target of the jump isn't compressed-minterlink-mips16,-mno-interlink-mips16โ aliases of-minterlink-compressedand-mno-interlink-compressed๐ฐ๏ธ These predate the microMIPS ASE and are kept around for backwards compatibility-mabi=32,-mabi=o64,-mabi=n32,-mabi=64,-mabi=eabiโ generates code for the given ABI ๐- The EABI has a 32-bit and a 64-bit variant ๐งฉ GCC normally generates 64-bit code when you pick a 64-bit architecture, but you can use
-mgp32to get 32-bit code instead - For info about the O64 ABI, check out
<http://gcc.gnu.org/projects/mipso64-abi.html>๐ - GCC supports a variant of the o32 ABI where the floating-point registers are 64 bits wide instead of 32 โจ You can select this combo with
-mabi=32 -mfp64. It relies on themthc1andmfhc1instructions, so it's only supported for MIPS32R2, MIPS32R3, and MIPS32R5 processors ๐ซถ - The register assignments for arguments and return values stay the same, but each scalar value gets passed in a single 64-bit register rather than a pair of 32-bit registers ๐
For example, scalar floating-point values are returned in
$f0only, not a$f0/$f1pair. The set of call-saved registers also stays the same, in that the even-numbered double-precision registers are saved ๐ฅฐ
- The EABI has a 32-bit and a 64-bit variant ๐งฉ GCC normally generates 64-bit code when you pick a 64-bit architecture, but you can use
Okay so bestie, there are two extra o32 ABI variants that help you transition from 32-bit to 64-bit registers ๐ฆ. They're -mfpxx and -mfp64 -mno-odd-spreg (aka FP64A) ๐
. FPXX is the flexible one: all code has to run correctly with 32-bit or 64-bit registers ๐ซถ. You can interlink it with FP32 or FP64, but not both at once ๐ญ. FP64A is basically FP64 but it bans odd-numbered single-precision registers ๐. Pair it with the "FRE" mode of FPUs in MIPS32R5 processors and FP32 and FP64A code can link together and run in the same process without switching FPU modes โจ iconic.
-mabicalls,-mno-abicallsโ Generate (or don't generate) code that fits SVR4-style dynamic objects ๐ธ.-mabicallsis the default on SVR4-based systems ๐.-mshared,-mno-sharedโ Generate (or don't generate) fully position-independent code that can slot into shared libraries ๐ง. This only affects-mabicallsโจ.
All -mabicalls code has traditionally been position-independent, no matter what -fPIC and -fpic say ๐. But as an extension, the GNU toolchain lets executables use absolute accesses for locally-binding symbols, use shorter GP initialization sequences, and generate direct calls to locally-defined functions. That's the mode -mno-shared selects ๐
.
-mno-shared needs binutils 2.16 or higher and makes objects that only the GNU linker can link ๐ฅ. The option doesn't change the ABI of the final executable, only the ABI of relocatable objects. Using -mno-shared usually makes executables both smaller and quicker ๐โโ๏ธ๐จ. -mshared is the default.
-mplt,-mno-pltโ Assume (or don't assume) that the static and dynamic linkers support PLTs and copy relocations ๐. This only affects-mno-shared -mabicalls. For the n64 ABI, it does nothing without-msym32๐.
You can make -mplt the default by configuring GCC with --with-mips-plt. Otherwise the default is -mno-plt ๐.
-mxgot,-mno-xgotโ Lift (or don't lift) the usual limits on how big the global offset table can be ๐.
GCC normally uses one instruction to load values from the GOT. That's pretty efficient, but it only works if the GOT is smaller than about 64k ๐ฌ. Anything bigger and the linker will throw something like this at you:
relocation truncated to fit: R_MIPS_GOT16 foobar
If that happens, recompile with -mxgot ๐ซถ. It works with very large GOTs, but the code is also less efficient, because it takes three instructions to fetch the value of a global symbol ๐.
Some linkers can create multiple GOTs. If you've got one of those, you should only need -mxgot when a single object file accesses more than 64k's worth of GOT entries. Very few linkers do ๐.
These options do nothing unless GCC is generating position-independent code ๐ง.
-mgp32โ Assume general-purpose registers are 32 bits wide ๐ธ.-mgp64โ Assume general-purpose registers are 64 bits wide ๐.-mfp32โ Assume floating-point registers are 32 bits wide โจ.-mfp64โ Assume floating-point registers are 64 bits wide ๐ฅ.-mfpxxโ Don't assume any particular width for floating-point registers ๐ฆ.-mhard-floatโ Use floating-point coprocessor instructions ๐ .-msoft-floatโ Don't use floating-point coprocessor instructions. Do the floating-point math with library calls instead ๐ซถ.-mno-floatโ Same as-msoft-float, but it also insists that the program never does any floating-point operations ๐ญ. This is only supported by some bare-metal MIPS configurations, which may pick a special set of libraries that lack all floating-point support (including, for example, the floating-point"printf"formats) ๐. If code compiled with-mno-floataccidentally contains floating-point operations, it'll probably fail at link time or run time ๐.-msingle-floatโ Assume the floating-point coprocessor only does single-precision operations ๐ธ.-mdouble-floatโ Assume the floating-point coprocessor does double-precision operations. This is the default ๐.-modd-spreg,-mno-odd-spregโ Enable (or don't enable) odd-numbered single-precision floating-point registers for the o32 ABI ๐. This is the default for processors known to support them. With the o32 FPXX ABI,-mno-odd-spregis set by default ๐.-mabs=2008,-mabs=legacyโ These control how special not-a-number (NaN) IEEE 754 floating-point data gets handled by the"abs.fmt"and"neg.fmt"machine instructions ๐.
By default, or when -mabs=legacy is used, the legacy treatment is selected ๐ง. Here, these instructions count as arithmetic and get avoided wherever correct operation matters and the input might be a NaN. Instead, a longer sequence that manipulates the sign bit by hand is used, unless -ffinite-math-only has also been specified ๐ญ.
-mabs=2008 selects the IEEE 754-2008 treatment โจ. These instructions count as non-arithmetic, so they operate correctly in all cases, including when the input operand is a NaN. They're always used for the respective operations ๐
.
-mnan=2008,-mnan=legacyโ These control the encoding of special not-a-number (NaN) IEEE 754 floating-point data ๐ฆ.
-mnan=legacy selects the legacy encoding ๐ธ. Here, quiet NaNs (qNaNs) are marked by the first bit of their trailing significand field being 0, and signaling NaNs (sNaNs) are marked by that first bit being 1 ๐.
-mnan=2008 selects the IEEE 754-2008 encoding ๐ฅ. Here, qNaNs have that first bit set to 1, and sNaNs have it set to 0 โจ.
The default is -mnan=legacy, unless GCC was configured with --with-nan=2008 ๐.
-mllsc,-mno-llscโ Use (or don't use) thell,sc, andsyncinstructions to implement atomic memory built-in functions ๐. If you specify neither, GCC uses those instructions as long as the target architecture supports them ๐ซถ.
-mllsc is handy if the runtime environment can emulate the instructions, and -mno-llsc can be useful when compiling for nonstandard ISAs ๐ง. You can make either one the default by configuring GCC with --with-llsc or --without-llsc respectively. --with-llsc is the default for some configurations; check the installation documentation for details ๐.
-mdsp,-mno-dspโ Use (or don't use) revision 1 of the MIPS DSP ASE ๐ . This defines the preprocessor macro"__mips_dsp", and it also defines"__mips_dsp_rev"to 1 โจ.-mdspr2,-mno-dspr2โ Use (or don't use) revision 2 of the MIPS DSP ASE ๐ฆ. This defines the preprocessor macros"__mips_dsp"and"__mips_dspr2", and it also defines"__mips_dsp_rev"to 2 ๐.-msmartmips,-mno-smartmipsโ Use (or don't use) the MIPS SmartMIPS ASE ๐ธ.-mpaired-single,-mno-paired-singleโ Use (or don't use) paired-single floating-point instructions ๐. This needs hardware floating-point support to be enabled ๐.-mdmx,-mno-mdmxโ Use (or don't use) MIPS Digital Media Extension instructions ๐ฅ. This can only be used when generating 64-bit code, and it requires hardware floating-point support to be enabled ๐.-mips3d,-mno-mips3dโ Use (or don't use) the MIPS-3D ASE ๐ง. The option-mips3dimplies-mpaired-singleโจ.-mmicromips,-mno-micromipsโ Generate (or don't generate) microMIPS code ๐ซถ.
microMIPS code generation can also be controlled on a per-function basis with the "micromips" and "nomicromips" attributes ๐
.
-mmt,-mno-mtโ Use (or don't use) MT Multithreading instructions ๐.-mmcu,-mno-mcuโ Use (or don't use) the MIPS MCU ASE instructions ๐ธ.-meva,-mno-evaโ Use (or don't use) the MIPS Enhanced Virtual Addressing instructions ๐.-mvirt,-mno-virtโ Use (or don't use) the MIPS Virtualization (VZ) instructions ๐.-mxpa,-mno-xpaโ Use (or don't use) the MIPS eXtended Physical Address (XPA) instructions โจ.-mcrc,-mno-crcโ Use (or don't use) the MIPS Cyclic Redundancy Check (CRC) instructions ๐ฆ.-mginv,-mno-ginvโ Use (or don't use) the MIPS Global INValidate (GINV) instructions ๐.-mloongson-mmi,-mno-loongson-mmiโ Use (or don't use) the MIPS Loongson MultiMedia extensions Instructions (MMI) ๐ฅ.-mloongson-ext,-mno-loongson-extโ Use (or don't use) the MIPS Loongson EXTensions (EXT) instructions ๐.-mloongson-ext2,-mno-loongson-ext2โ Use (or don't use) the MIPS Loongson EXTensions r2 (EXT2) instructions ๐.-mlong64โ Force"long"types to be 64 bits wide ๐ง. Check out-mlong32for the lowdown on the default and how the pointer size gets determined ๐.-mlong32โ Force"long","int", and pointer types to be 32 bits wide ๐ธ.
The default sizes of "int"s, "long"s, and pointers depend on the ABI ๐ซถ. All the supported ABIs use 32-bit "int"s. The n64 ABI uses 64-bit "long"s, and so does the 64-bit EABI, but the others use 32-bit "long"s ๐
. Pointers are the same size as "long"s, or the same size as integer registers, whichever is smaller โจ.
-msym32,-mno-sym32โ Assume (or don't assume) that all symbols have 32-bit values, no matter which ABI you picked ๐ฆ. This is useful together with-mabi=64and-mno-abicalls, because it lets GCC generate shorter and faster references to symbolic addresses ๐.-G numโ Put definitions of externally-visible data in a small data section if that data is no bigger thannumbytes ๐. GCC can then generate more efficient accesses to the data; see-mgpoptfor details ๐ฅ.
The default -G option depends on the configuration ๐.
-mlocal-sdata,-mno-local-sdataโ Extend (or don't extend) the-Gbehaviour to local data too, like static variables in C ๐.-mlocal-sdatais the default for all configurations ๐.
If the linker is whining that an application is using too much small data, bestie, try rebuilding the less performance-critical parts with -mno-local-sdata ๐ฅบ. You might also want to build large libraries with -mno-local-sdata too, so they leave more room for the main program ๐ง
-mextern-sdata,-mno-extern-sdataโ This one is about data defined somewhere else ๐งณ. GCC will assume it lives in a small data section (or not assume, with-mno-extern-sdata) as long as it fits under the-Glimit.-mextern-sdatais the default for every configuration, periodt ๐
Okay, but this part is a big deal ๐ญ If you compile a module Mod with -mextern-sdata -G num -mgpopt, and Mod references a variable Var that is no bigger than num bytes, you must make sure Var is placed in a small data section. If another module defines Var, you must either compile that module with a high-enough -G setting or attach a "section" attribute to Var's definition. If Var is common, you must link the application with a high-enough -G setting.
The easiest way to keep this from going sideways is to compile and link every module with the same -G option ๐ซถ. But if you want to build a library that supports several different small data limits, compile it with the highest supported -G setting and also use -mno-extern-sdata, so the library stops making assumptions about externally-defined data ๐ธ
-mgpopt,-mno-gpoptโ Use (or don't use) GP-relative accesses for symbols that are known to be in a small data section. See-G,-mlocal-sdataand-mextern-sdata๐ฆ-mgpoptis the default for all configurations.
-mno-gpopt is useful when the $gp register might not hold the value of "_gp". For example, if the code is part of a library that might be used in a boot monitor, programs that call boot monitor routines pass an unknown value in $gp. (In those situations, the boot monitor itself is usually compiled with -G0.)
-mno-gpopt implies -mno-local-sdata and -mno-extern-sdata. Keep that in mind, it's giving domino effect ๐
-membedded-data,-mno-embedded-dataโ Variables go to the read-only data section first if possible, then the small data section if possible, and otherwise into data. The code comes out slightly slower than the default, but it uses less RAM while running, so some embedded systems might prefer it โจ-muninit-const-in-rodata,-mno-uninit-const-in-rodataโ Puts uninitialized"const"variables in the read-only data section. This only means something when you're also using-membedded-data๐-mcode-readable=settingโ Tells GCC whether it's allowed to generate code that reads from executable sections. There are three settings to choose from ๐-mcode-readable=yesโ Instructions can freely access executable sections. This is the default, so you're probably already here ๐-mcode-readable=pcrelโ MIPS16 PC-relative load instructions can access executable sections, but other instructions must not. This is useful on 4KSc and 4KSd processors when the code TLBs have the Read Inhibit bit set. It's also handy on processors that can be configured with a dual instruction/data SRAM interface and that, like the M4K, automatically redirect PC-relative loads to the instruction RAM ๐ง-mcode-readable=noโ Instructions must not access executable sections. This can be useful on targets configured with a dual instruction/data SRAM interface that (unlike the M4K) do not automatically redirect PC-relative loads to the instruction RAM ๐
-msplit-addresses,-mno-split-addressesโ Turns the%hi()and%lo()assembler relocation operators on (or off). This has been superseded by-mexplicit-relocs, but it's kept around for backwards compatibility ๐-mexplicit-relocs,-mno-explicit-relocsโ Uses (or doesn't use) assembler relocation operators when dealing with symbolic addresses. The alternative, picked by-mno-explicit-relocs, is to use assembler macros instead.-mexplicit-relocsis the default if GCC was configured to use an assembler that supports relocation operators ๐ฅ-mcheck-zero-division,-mno-check-zero-divisionโ Traps (or doesn't trap) on integer division by zero ๐ The default is-mcheck-zero-division.-mdivide-traps,-mdivide-breaksโ MIPS systems check for division by zero by generating either a conditional trap or a break instruction. Traps give you smaller code, but they're only supported on MIPS II and later. Also, some versions of the Linux kernel have a bug that stops trap from generating the proper signal ("SIGFPE"). So-mdivide-trapslets conditional traps happen on architectures that support them, and-mdivide-breaksforces the use of breaks ๐ญ
The default is usually -mdivide-traps, but you can override that at configure time with --with-divide=breaks. Divide-by-zero checks can be completely disabled with -mno-check-zero-division.
-mload-store-pairs,-mno-load-store-pairsโ Turns an optimization on (or off) that pairs consecutive load or store instructions so they can do load/store bonding ๐ฆ It's on by default, but it only takes effect when the selected architecture is known to support bonding.-mmemcpy,-mno-memcpyโ Forces (or doesn't force) the use of"memcpy"for non-trivial block moves. The default is-mno-memcpy, which lets GCC inline most constant-sized copies ๐-mlong-calls,-mno-long-callsโ Disables (or doesn't disable) use of thejalinstruction. Calling functions withjalis more efficient, but it requires the caller and callee to be in the same 256 megabyte segment. This option has no effect on abicalls code. The default is-mno-long-callsโญ-mmad,-mno-madโ Enables (or disables) use of the"mad","madu"and"mul"instructions, as provided by the R4650 ISA ๐ธ-mimadd,-mno-imaddโ Enables (or disables) use of the"madd"and"msub"integer instructions. The default is-mimaddon architectures that support"madd"and"msub", except for the 74k architecture, where it was found to generate slower code ๐-mfused-madd,-mno-fused-maddโ Enables (or disables) use of the floating-point multiply-accumulate instructions, when they're available. The default is-mfused-madd๐ง
Heads up on the R8000 CPU: when multiply-accumulate instructions are used, the intermediate product is calculated to infinite precision and is not subject to the FCSR Flush to Zero bit. That may be undesirable in some circumstances ๐ฌ On other processors the result is numerically identical to the equivalent computation using separate multiply, add, subtract and negate instructions.
-nocppโ Tells the MIPS assembler to not run its preprocessor over user assembler files (with a.ssuffix) when assembling them ๐ โโ๏ธ-mfix-24k,-mno-fix-24kโ Works around the 24K E48 (lost data on stores during refill) errata ๐ฉน The workarounds are implemented by the assembler rather than by GCC.-mfix-r4000,-mno-fix-r4000โ Works around certain R4000 CPU errata:- A double-word or a variable shift may give an incorrect result if executed immediately after starting an integer division.
- A double-word or a variable shift may give an incorrect result if executed while an integer multiplication is in progress.
- An integer division may give an incorrect result if started in a delay slot of a taken branch or a jump.
-mfix-r4400,-mno-fix-r4400โ Works around certain R4400 CPU errata:- A double-word or a variable shift may give an incorrect result if executed immediately after starting an integer division.
-mfix-r10000,-mno-fix-r10000โ Works around certain R10000 errata ๐ง"ll"/"sc"sequences may not behave atomically on revisions prior to 3.0. They may deadlock on revisions 2.6 and earlier.
This option can only be used if the target architecture supports branch-likely instructions. -mfix-r10000 is the default when -march=r10000 is used; -mno-fix-r10000 is the default otherwise.
-mfix-r5900,-mno-fix-r5900โ Don't try to schedule the preceding instruction into the delay slot of a branch instruction placed at the end of a short loop of six instructions or fewer. Instead, always schedule a"nop"instruction there ๐ซถ The short loop bug can, under certain conditions, cause loops to execute only once or twice, due to a hardware bug in the R5900 chip. The workaround is implemented by the assembler rather than by GCC.-mfix-rm7000,-mno-fix-rm7000โ Works around the RM7000"dmult"/"dmultu"errata. The workarounds are implemented by the assembler rather than by GCC ๐-mfix-vr4120,-mno-fix-vr4120โ Works around certain VR4120 errata:"dmultu"does not always produce the correct result."div"and"ddiv"do not always produce the correct result if one of the operands is negative.
The workarounds for the division errata rely on special functions in libgcc.a. At the moment, these functions are only provided by the "mips64vr*-elf" configurations ๐ค
Other VR4120 errata require a NOP to be inserted between certain pairs of instructions. Those are handled by the assembler, not by GCC itself.
-mfix-vr4130โ Works around the VR4130"mflo"/"mfhi"errata. The workarounds are implemented by the assembler rather than by GCC, although GCC avoids using"mflo"and"mfhi"if the VR4130"macc","macchi","dmacc"and"dmacchi"instructions are available instead โจ-mfix-sb1,-mno-fix-sb1โ Works around certain SB-1 CPU core errata. (This flag currently works around the SB-1 revision 2"F1"and"F2"floating-point errata.) ๐-mr10k-cache-barrier=settingโ Specifies whether GCC should insert cache barriers to avoid the side effects of speculation on R10K processors ๐ง
Like a lot of processors, the R10K tries to predict the outcome of a conditional branch and speculatively executes instructions from the "taken" branch. It later aborts those instructions if the predicted outcome was wrong. But on the R10K, even aborted instructions can have side effects ๐
okay so this problem only hits kernel stores and, depending on the system, kernel loads ๐ญ a speculatively-executed store can pull the target memory into cache and mark that cache line as dirty, even if the store itself gets aborted later ๐ then if a DMA operation writes to that same memory before the "dirty" line is flushed, the cached data overwrites the DMA-ed data ๐ see the R10K processor manual for the full tea, including other potential problems ๐
one workaround is to slot cache barrier instructions in front of every memory access that might get speculatively executed and that might have side effects even if it's aborted ๐งฑ -mr10k-cache-barrier=setting is the knob that controls GCC's version of this fix ๐๏ธ it assumes that aborted accesses to any byte in these regions don't have side effects:
- the memory occupied by the current function's stack frame;
- the memory occupied by an incoming stack argument;
- the memory occupied by an object with a link-time-constant address.
making sure speculative accesses to these regions are actually safe is the kernel's job, not GCC's ๐
if the input program has a function declaration like this:
void foo (void);
then the implementation of foo has to let j foo and jal foo run speculatively ๐ฆ GCC respects this rule for functions it compiles itself ๐
it expects non-GCC functions (think hand-written assembly code) to play by the same rules ๐
this option comes in three flavors ๐ธ
-mr10k-cache-barrier=load-storeโ drops a cache barrier in front of any load or store that might get speculatively executed and that might have side effects even if aborted ๐ฅ-mr10k-cache-barrier=storeโ same vibe, but only stores get a barrier ๐ฉท-mr10k-cache-barrier=noneโ turns off cache barrier insertion entirely. This is the default setting ๐ซถ-mflush-func=func,-mno-flush-funcโ picks which function gets called to flush the I and D caches, or tells GCC to skip calling any flush function at all ๐งน if you do call one, it has to take the same arguments as the common_flush_func: the address of the memory range being flushed, the size of that range, and the number 3 (which flushes both caches) โจ the default depends on what target GCC was configured for, but it's usually_flush_funcor__cpu_flush๐ธmbranch-cost=numโ sets the cost of branches to roughly num "simple" instructions. This cost is only a heuristic and isn't guaranteed to give consistent results across releases ๐คทโโ๏ธ a zero cost redundantly selects the default, which is based on the -mtune setting ๐-mbranch-likely,-mno-branch-likelyโ enables or disables Branch Likely instructions, no matter what the selected architecture defaults to ๐ by default, Branch Likely instructions may be generated if the selected architecture supports them. The exception is the MIPS32 and MIPS64 architectures (and processors that implement them): for those, Branch Likely instructions aren't generated by default, because those architectures specifically deprecate their use ๐ โโ๏ธ-mcompact-branches=never,-mcompact-branches=optimal,-mcompact-branches=alwaysโ these options control which form of branches gets generated ๐ฆ the default is-mcompact-branches=optimalโจ-mcompact-branches=nevermakes sure compact branch instructions are never generated ๐ซ-mcompact-branches=alwaysmakes sure a compact branch instruction gets generated if one is available. If it isn't, a delay slot form of the branch is used instead ๐โโ๏ธ
this option is supported from MIPS Release 6 onwards ๐
-mcompact-branches=optimaluses a delay slot branch if one is available in the current ISA and the delay slot gets successfully filled. If the delay slot isn't filled, a compact branch gets chosen if one is available ๐ง
-mfp-exceptions,-mno-fp-exceptionsโ specifies whether FP exceptions are enabled. This affects how FP instructions are scheduled for some processors ๐ถ the default is that FP exceptions are enabled ๐
for instance, on the SB-1, if FP exceptions are disabled and we're emitting 64-bit code, then we can use both FP pipes. Otherwise, we can only use one FP pipe ๐ง
-mvr4130-align,-mno-vr4130-alignโ the VR4130 pipeline is two-way superscalar, but it can only issue two instructions together if the first one is 8-byte aligned ๐ค when this option is enabled, GCC aligns pairs of instructions that it thinks should execute in parallel ๐
this option only has an effect when optimizing for the VR4130. It normally makes code faster, but at the expense of making it bigger ๐ฆ it's enabled by default at optimization level -O3 โญ
-msynci,-mno-synciโ enables (or disables) generation of "synci" instructions on architectures that support it ๐ ๏ธ the "synci" instructions (if enabled) are generated when "__builtin___clear_cache" is compiled ๐
this option defaults to -mno-synci, but you can override that default by configuring GCC with --with-synci ๐ง when compiling code for single processor systems, it's generally safe to use "synci" ๐
โ ๏ธ heads up, bestie: on many multi-core (SMP) systems, "synci" doesn't invalidate the instruction caches on all cores and may lead to undefined behavior ๐
-mrelax-pic-calls,-mno-relax-pic-callsโ tries to turn PIC calls that are normally dispatched via register$25into direct calls ๐ฆ this is only possible if the linker can resolve the destination at link time and if the destination is within range for a direct call ๐
-mrelax-pic-calls is the default if GCC was configured to use an assembler and a linker that support the ".reloc" assembly directive and -mexplicit-relocs is in effect. With -mno-explicit-relocs, this optimization can be done by the assembler and the linker alone, without help from the compiler ๐ซถ
-mmcount-ra-address,-mno-mcount-ra-addressโ emits (or doesn't emit) code that lets "_mcount" modify the calling function's return address ๐ฎ when enabled, this option extends the usual "_mcount" interface with a new ra-address parameter. It has type "intptr_t *" and is passed in register$12๐ฏ "_mcount" can then modify the return address by doing both of the following:- returning the new address in register
$31 - storing the new address in "*ra-address", if ra-address is nonnull
- returning the new address in register
the default is -mno-mcount-ra-address ๐
-mframe-header-opt,-mno-frame-header-optโ enables (or disables) frame header optimization in the o32 ABI ๐งบ when using the o32 ABI, calling functions allocate 16 bytes on the stack for the called function to write out register arguments. When enabled, this optimization suppresses that frame header allocation if it can be determined that it's unused ๐งน
this optimization is off by default at all optimization levels ๐
-mlxc1-sxc1,-mno-lxc1-sxc1โ when applicable, enables (or disables) generation of "lwxc1", "swxc1", "ldxc1", and "sdxc1" instructions. Enabled by default โจ-mmadd4,-mno-madd4โ when applicable, enables (or disables) generation of 4-operand "madd.s", "madd.d", and related instructions. Enabled by default ๐
๐ MMIX Options ๐
these options are defined for the MMIX:
-mlibfuncs,-mno-libfuncsโ specifies that intrinsic library functions are being compiled, passing all values in registers, no matter the size ๐งฉ-mepsilon,-mno-epsilonโ generates floating-point comparison instructions that compare with respect to the "rE" epsilon register ๐ฏ-mabi=mmixware,-mabi=gnuโ generates code that passes function parameters and return values that (in the called function) are seen as registers$0and up ๐ธ the GNU ABI does it differently, using global registers$231and up ๐-mzero-extend,-mno-zero-extendโ when reading data from memory in sizes shorter than 64 bits, uses (or doesn't use) zero-extending load instructions by default, instead of sign-extending ones ๐-mknuthdiv,-mno-knuthdivโ makes the result of a division that yields a remainder have the same sign as the divisor. With the default,-mno-knuthdiv, the sign of the remainder follows the sign of the dividend. Both methods are arithmetically valid, though the latter is almost exclusively used ๐งฎ-mtoplevel-symbols,-mno-toplevel-symbolsโ prepends (or doesn't prepend) a:to all global symbols, so the assembly code can be used with the "PREFIX" assembly directive ๐งโโ๏ธ-melfโ generates an executable in the ELF format, instead of the default mmo format used by the mmix simulator ๐ฆ-mbranch-predict,-mno-branch-predictโ uses (or doesn't use) the probable-branch instructions, when static branch prediction indicates a probable branch ๐ฎ-mbase-addresses,-mno-base-addressesโ generates (or doesn't generate) code that uses base addresses. Using a base address automatically generates a request (handled by the assembler and the linker) for a constant to be set up in a global register. That register is used for one or more base address requests within the range 0 to 255 from the value held in the register. This generally leads to short and fast code, but the number of different data items that can be addressed is limited ๐ so a program that uses lots of static data may need-mno-base-addresses๐-msingle-exit,-mno-single-exitโ forces (or doesn't force) generated code to have a single exit point in each function ๐ช
๐ MN10300 Options ๐
these -m options are defined for Matsushita MN10300 architectures:
-mmult-bugโ generates code to avoid bugs in the multiply instructions for the MN10300 processors. This is the default ๐ก๏ธ-mno-mult-bugโ does not generate code to avoid bugs in the multiply instructions for the MN10300 processors ๐-mam33โ generates code using features specific to the AM33 processor ๐-mno-am33โ does not generate code using features specific to the AM33 processor. This is the default ๐ท-mam33-2โ generates code using features specific to the AM33/2.0 processor ๐-mam34โ okay bestie, this one unlocks features made specifically for the AM34 processor ๐ โจ-mtune=cpu-typeโ tells the scheduler which CPU's timing to vibe with when it lines up instructions ๐ It does not change the processor you're targeting, so no glow-up there. The CPU type has to be one ofmn10300,am33,am33-2oram34๐ฆ-mreturn-pointer-on-d0โ when a function returns a pointer, this puts that pointer in botha0andd0๐ซถ Without it, the pointer only goes ina0, and calling those functions without a prototype throws errors ๐ญ Heads up: this one is on by default. If you want it off, use-mno-return-pointer-on-d0๐-mno-crt0โ skips linking the C run-time initialization object file ๐ธ-mrelaxโ tells the linker to run a relaxation pass that shortens branches, calls and absolute memory addresses ๐ฅ This only does anything when you pass it on the command line for the final link step ๐
โ ๏ธ bestie, this one makes symbolic debugging impossible. Think before you flip it on ๐
-mliwโ lets the compiler generate Long Instruction Word instructions when the target is AM33 or later ๐ This is the default, and it defines the preprocessor macro__LIW__โจ-mno-liwโ no LIW instructions for you ๐ โโ๏ธ This one defines the preprocessor macro__NO_LIW__๐ซฅ-msetlbโ allows the compiler to generate SETLB and Lcc instructions when the target is AM33 or later ๐ง This is the default, and it defines the preprocessor macro__SETLB__๐-mno-setlbโ blocks SETLB and Lcc instructions entirely ๐ฅ It defines the preprocessor macro__NO_SETLB__๐
๐ฆ Moxie Options ๐ฆ
okay so these are the options defined for Moxie, and they're giving very specific vibes ๐ธ
-mebโ generates big-endian code ๐ This is the default formoxie-*-*configurations ๐-melโ generates little-endian code ๐-mmul.xโ generatesmul.xandumul.xinstructions โจ This is the default formoxiebox-*-*configurations ๐ง-mno-crt0โ skips linking the C run-time initialization object file, same as before, periodt ๐
๐ MSP430 Options ๐
these options are defined for the MSP430, so if that's your chip, pay attention bestie ๐
-masm-hexโ forces assembly output to always use hex constants ๐ Normally these show up as signed decimals, but this option is there for testsuite and/or aesthetic purposes ๐-mmcu=โ selects the MCU you're targeting ๐ฆ The name gets converted to upper case, wrapped with__before and after, and turned into a C preprocessor symbol ๐ Themsp430.hheader then uses that symbol to pick an MCU-specific supplementary header file ๐ซถ
The option also sets the ISA to use ๐ฅ If the MCU name is known to only support the 430 ISA, that's what gets selected. Otherwise the 430X ISA is selected ๐
A generic MCU name of msp430 selects the 430 ISA, and the generic msp430x MCU name selects the 430X ISA โจ
On top of that, an MCU-specific linker script gets added to the linker command line ๐ธ The script's name is the MCU name with .ld appended. So -mmcu=xxx on the gcc command line defines the C preprocessor symbol __XXX__ and makes the linker search for a script called xxx.ld ๐ง
The ISA and hardware multiply support for each MCU is hard-coded into GCC ๐ But if you need more devices than that list covers, an external devices.csv file can extend device support ๐
GCC looks for devices.csv using the methods below, in order of precedence. The first method beats the second, and the second beats the third ๐
- Include path specified with
-Iand-Lโdevices.csvgets searched for in each directory listed as an include path or a linker library search path ๐ - Path specified by the environment variable
MSP430_GCC_INCLUDE_DIRโ set this global environment variable to the full path of the directory containingdevices.csv, and GCC searches that directory for it ๐ฆ If the file is found, that directory also gets registered as an include path and a linker library path ๐ Header files and linker scripts in there can be used without manually specifying-Iand-Lon the command line ๐ซถ - The
msp430-elf{,bare}/include/devicesdirectory โ last stop: GCC checksmsp430-elf{,bare}/include/devicesfrom the toolchain root directory ๐ฅ This directory doesn't exist in a default installation, but if you've made it and copieddevices.csvin there, the MCU data gets read ๐ Just like above, this directory also gets registered as an include path and linker library path โจ
If none of those search methods find devices.csv, the hard-coded MCU data is used ๐ธ
-mwarn-mcu,-mno-warn-mcuโ this option enables or disables warnings about conflicts between the MCU name from-mmcuand the ISA set by-mcpuand/or the hardware multiply support set by-mhwmult๐ It also toggles warnings about unrecognized MCU names ๐ง It's on by default ๐-mcpu=โ specifies the ISA to use ๐ฅ Accepted values aremsp430,msp430xandmsp430xv2๐ This option is deprecated, so use-mmcu=to select the ISA instead ๐-msimโ links to the simulator runtime libraries and linker script ๐ฆ This overrides any scripts that would've been selected by-mmcu=๐-mlargeโ uses large-model addressing, with 20-bit pointers and a 32-bitsize_t๐ฅ-msmallโ uses small-model addressing, with 16-bit pointers and a 16-bitsize_t๐ซถ-mrelaxโ this one gets passed to the assembler and linker ๐ It lets the linker do certain optimizations that can't happen until the final link โจ-mhwmult=โ describes the type of hardware multiply the target supports ๐ Accepted values arenonefor no hardware multiply,16bitfor the original 16-bit-only multiply from early MCUs,32bitfor the 16/32-bit multiply in later MCUs, andf5seriesfor the 16/32-bit multiply in F5-series MCUs ๐ง You can also giveauto, which tells GCC to figure out the hardware multiply support from the MCU name you passed with-mmcu๐ If there's no-mmcuoption, or the MCU name isn't recognized, no hardware multiply support is assumed ๐ญautois the default setting ๐ธ
Hardware multiplies are normally done by calling a library routine, which saves space in the generated code ๐ When you compile at -O3 or higher, though, the hardware multiplier gets invoked inline ๐ฅ That makes the code bigger, but faster ๐
The hardware multiply routines disable interrupts while they run and restore the previous interrupt state when they finish ๐ซถ So they're safe to use inside interrupt handlers as well as in normal code ๐
-minrtโ enables a minimum runtime environment with no static initializers or constructors ๐ฅ It's meant for memory-constrained devices ๐ The compiler puts special symbols in some objects that tell the linker and runtime which code fragments are required ๐ฆ-mtiny-printfโ enables reduced code sizeprintfandputslibrary functions ๐ These tiny versions are not reentrant, so be careful with them in multi-threaded apps ๐ฌ
Stream support has been removed, and the string to print always goes to stdout via the write syscall ๐ง The string isn't buffered before it's sent to write ๐
This option requires Newlib Nano IO, so GCC must be configured with --enable-newlib-nano-formatted-io โจ
-mcode-region=,-mdata-region=โ these tell the compiler where to place functions and data that don't have one of thelower,upper,eitherorsectionattributes ๐ซถ The possible values arelower,upper,eitherorany, and the first three behave like the matching attribute ๐ The fourth value,any, is the default ๐ฅ It leaves placement entirely up to the linker script and how it assigns the standard sections (.text,.data, etc) to the memory regions ๐ธ-msilicon-errata=โ passes a request to the assembler to enable the fixes for the named silicon errata ๐ฆ-msilicon-errata-warn=โ passes a request to the assembler to enable warning messages for when a silicon errata might need to be applied ๐-mwarn-devices-csv,-mno-warn-devices-csvโ warns ifdevices.csvisn't found or there are problems parsing it ๐ง Default is on ๐
๐ NDS32 Options ๐
these options are defined for NDS32 implementations, so let's get into it ๐
-mbig-endianโ generates code in big-endian mode ๐-mlittle-endianโ generates code in little-endian mode ๐-mreduced-regsโ uses reduced-set registers for register allocation ๐ฅ-mfull-regsโ uses full-set registers for register allocation ๐-mcmovโ generates conditional move instructions โจ-mno-cmovโ does not generate conditional move instructions ๐ โโ๏ธ-mext-perfโ generates performance extension instructions ๐ฅ-mno-ext-perfโ does not generate performance extension instructions ๐ธ-mext-perf2โ generates performance extension 2 instructions ๐ฆ-mno-ext-perf2โ does not generate performance extension 2 instructions ๐ซถ-mext-stringโ generates string extension instructions ๐ง-mno-ext-stringโ does not generate string extension instructions ๐-mv3pushโ generates v3push25/pop25instructions ๐-mno-v3pushโ does not generate v3push25/pop25instructions ๐ฅ-m16-bitโ generates 16-bit instructions ๐-mno-16-bitโ does not generate 16-bit instructions ๐-misr-vector-size=numโ specifies the size of each interrupt vector, which must be4or16๐-mcache-block-size=numโ specifies the size of each cache block, which must be a power of 2 between4and512๐-march=archโ specifies the name of the target architecture ๐ง-mcmodel=code-modelโ sets the code model to one of the values below ๐smallโ all the data and read-only data segments must be within 512KB of addressing space ๐ธ The text segment must be within 16MB of addressing space ๐ฅ
medium: Okay bestie, the data segment has to squeeze into 512KB, but the read-only data can roam anywhere in a 4GB addressing space. ๐ The text segment should still stay within 16MB addressing space. ๐ซถlarge: All the text and data segments can live within a 4GB addressing space. โจ-mctor-dtor: Turns on the constructor/destructor feature. ๐-mrelax: Tells the linker to relax instructions. ๐ฆ
๐ธ Nios II Options ๐ธ
These are the options defined for the Altera Nios II processor. ๐
-G num: Puts global and static objects that are less than or equal to num bytes into the small data or BSS sections instead of the normal data or BSS sections. The default value of num is8. ๐-mgpopt=option,-mgpopt,-mno-gpopt: Okay so these control whether GP-relative accesses get generated (or not!). The following option names are recognized:none: Do not generate GP-relative accesses. ๐local: Generate GP-relative accesses for small data objects that are not external, weak, or uninitialized common symbols. Also use GP-relative addressing for objects that have been explicitly placed in a small data section via a"section"attribute. โจglobal: As forlocal, but also generate GP-relative accesses for small data objects that are external, weak, or common. If you use this option, you must ensure that all parts of your program (including libraries) are compiled with the same-Gsetting. ๐data: Generate GP-relative accesses for all data objects in the program. If you use this option, the entire data and BSS segments of your program must fit in 64K of memory and you must use an appropriate linker script to allocate them within the addressable range of the global pointer. ๐ญall: Generate GP-relative addresses for function pointers as well as data pointers. If you use this option, the entire text, data, and BSS segments of your program must fit in 64K of memory and you must use an appropriate linker script to allocate them within the addressable range of the global pointer. ๐ฅ
-mgpopt is equivalent to -mgpopt=local, and -mno-gpopt is equivalent to -mgpopt=none. ๐ง
The default is -mgpopt except when -fpic or -fPIC is specified to generate position-independent code.
Heads up: the Nios II ABI does not permit GP-relative accesses from shared libraries. ๐ซ
You may need to specify -mno-gpopt explicitly when building programs that include large amounts of small data, including large GOT data sections. In this case, the 16-bit offset for GP-relative addressing may not be large enough to allow access to the entire small data section. ๐
-mgprel-sec=regexp: This option specifies additional section names that can be accessed via GP-relative addressing. It is most useful in conjunction with"section"attributes on variable declarations and a custom linker script. The regexp is a POSIX Extended Regular Expression. This option does not affect the behavior of the-Goption, and the specified sections are in addition to the standard".sdata"and".sbss"small-data sections that are recognized by-mgpopt. ๐งฉ-mr0rel-sec=regexp: This option specifies names of sections that can be accessed via a 16-bit offset from"r0"; that is, in the low 32K or high 32K of the 32-bit address space. It is most useful in conjunction with"section"attributes on variable declarations and a custom linker script. The regexp is a POSIX Extended Regular Expression. In contrast to the use of GP-relative addressing for small data, zero-based addressing is never generated by default and there are no conventional section names used in standard linker scripts for sections in the low or high areas of memory. ๐ฆ-mel,-meb: Generate little-endian (default) or big-endian (experimental) code, respectively. ๐-march=arch: This specifies the name of the target Nios II architecture. GCC uses this name to determine what kind of instructions it can emit when generating assembly code. Permissible names are:r1,r2. The preprocessor macro"__nios2_arch__"is available to programs, with value1or2, indicating the targeted ISA level. ๐ฏ-mbypass-cache,-mno-bypass-cache: Forces all load and store instructions to always bypass the cache by using I/O variants of the instructions. The default is not to bypass the cache. ๐โโ๏ธ-mno-cache-volatile,-mcache-volatile: Volatile memory accesses bypass the cache using the I/O variants of the load and store instructions. The default is not to bypass the cache. ๐-mno-fast-sw-div,-mfast-sw-div: Do not use table-based fast divide for small numbers. The default is to use the fast divide at-O3and above. โ-mno-hw-mul,-mhw-mul,-mno-hw-mulx,-mhw-mulx,-mno-hw-div,-mhw-div: Enable or disable emitting themul,mulx, anddivfamily of instructions by the compiler. The default is to emitmuland not emitdivandmulx. โ๏ธ-mbmx,-mno-bmx,-mcdx,-mno-cdx: Enable or disable generation of Nios II R2 BMX (bit manipulation) and CDX (code density) instructions. Enabling these instructions also requires-march=r2. Since these instructions are optional extensions to the R2 architecture, the default is not to emit them. ๐ง-mcustom-insn=N,-mno-custom-insn: Each-mcustom-insn=Noption enables use of a custom instruction with encodingNwhen generating code that uses insn. For example,-mcustom-fadds=253generates custom instruction 253 for single-precision floating-point add operations instead of the default behavior of using a library call. ๐ง
The following values of insn are supported. Except as otherwise noted, floating-point operations are expected to be implemented with normal IEEE 754 semantics and correspond directly to the C operators or the equivalent GCC built-in functions. ๐ค
Single-precision floating point
fadds,fsubs,fdivs,fmuls: Binary arithmetic operations.fnegs: Unary negation.fabss: Unary absolute value.fcmpeqs,fcmpges,fcmpgts,fcmples,fcmplts,fcmpnes: Comparison operations.fmins,fmaxs: Floating-point minimum and maximum. These instructions are only generated if-ffinite-math-onlyis specified.fsqrts: Unary square root operation.fcoss,fsins,ftans,fatans,fexps,flogs: Floating-point trigonometric and exponential functions. These instructions are only generated if-funsafe-math-optimizationsis also specified.
Double-precision floating point
faddd,fsubd,fdivd,fmuld: Binary arithmetic operations.fnegd: Unary negation.fabsd: Unary absolute value.fcmpeqd,fcmpged,fcmpgtd,fcmpled,fcmpltd,fcmpned: Comparison operations.fmind,fmaxd: Double-precision minimum and maximum. These instructions are only generated if-ffinite-math-onlyis specified.fsqrtd: Unary square root operation.fcosd,fsind,ftand,fatand,fexpd,flogd: Double-precision trigonometric and exponential functions. These instructions are only generated if-funsafe-math-optimizationsis also specified.
Conversions
fextsd: Conversion from single precision to double precision.ftruncds: Conversion from double precision to single precision.fixsi,fixsu,fixdi,fixdu: Conversion from floating point to signed or unsigned integer types, with truncation towards zero.round: Conversion from single-precision floating point to signed integer, rounding to the nearest integer and ties away from zero. This corresponds to the"__builtin_lroundf"function when-fno-math-errnois used.floatis,floatus,floatid,floatud: Conversion from signed or unsigned integer types to floating-point types.
In addition, all of the following transfer instructions for internal registers X and Y must be provided to use any of the double-precision floating-point instructions. Custom instructions taking two double-precision source operands expect the first operand in the 64-bit register X. The other operand (or only operand of a unary operation) is given to the custom arithmetic instruction with the least significant half in source register src1 and the most significant half in src2. A custom instruction that returns a double-precision result returns the most significant 32 bits in the destination register and the other half in 32-bit register Y. GCC automatically generates the necessary code sequences to write register X and/or read register Y when double-precision floating-point instructions are used. ๐ง
fwrx: Writesrc1into the least significant half ofXandsrc2into the most significant half ofX.fwry: Writesrc1intoY.frdxhi,frdxlo: Read the most or least (respectively) significant half ofXand store it indest.frdy: Read the value ofYand store it intodest.
Note that you can gain more local control over generation of Nios II custom instructions by using the target("custom-insn=N") and target("no-custom-insn") function attributes or pragmas. ๐
-mcustom-fpu-cfg=name: This option enables a predefined, named set of custom instruction encodings (see-mcustom-insnabove). Currently, the following sets are defined:-mcustom-fpu-cfg=60-1is equivalent to:-mcustom-fmuls=252 -mcustom-fadds=253 -mcustom-fsubs=254 -fsingle-precision-constant-mcustom-fpu-cfg=60-2is equivalent to:-mcustom-fmuls=252 -mcustom-fadds=253 -mcustom-fsubs=254 -mcustom-fdivs=255 -fsingle-precision-constant-mcustom-fpu-cfg=72-3is equivalent to:-mcustom-floatus=243 -mcustom-fixsi=244 -mcustom-floatis=245 -mcustom-fcmpgts=246 -mcustom-fcmples=249 -mcustom-fcmpeqs=250 -mcustom-fcmpnes=251 -mcustom-fmuls=252 -mcustom-fadds=253 -mcustom-fsubs=254 -mcustom-fdivs=255 -fsingle-precision-constant
Custom instruction assignments given by individual -mcustom-insn= options override those given by -mcustom-fpu-cfg=, regardless of the order of the options on the command line. ๐
Okay so, you can get way more local control over which FPU configuration you're using by slapping target("custom-fpu-cfg=name") on as a function attribute or pragma ๐โจ
These additional -m options are available for the Altera Nios II ELF (bare-metal) target ๐ง
-mhalโ Links with the HAL BSP ๐ This skips linking the GCC-provided C runtime startup and termination code, and it's usually paired with-msys-crt0=so you can point at the alternate startup code the HAL BSP brings along ๐-msmallcโ Links with a limited C library,-lsmallc, instead of Newlib ๐ธ-msys-crt0=startfileโstartfileis the name of the startfile (crt0) you want when linking ๐ฆ This only does anything alongside-mhal, so don't expect magic without it ๐-msys-lib=systemlibโsystemlibis the name of the library that supplies the low-level system calls the C library needs, likereadandwrite๐ซถ This is usually how you link against a library from a HAL BSP
โจ Nvidia PTX Options โจ
These options are defined for Nvidia PTX ๐
-m32,-m64โ Generates code for the 32-bit or 64-bit ABI ๐ฅ-misa=ISA-stringโ Generates code for the PTX ISA you specify, likesm_35๐ ISA strings have to be lower-case, and valid ones includesm_30andsm_35. The default issm_30๐-mmainkernelโ Links in code for a__mainkernel ๐ง This is for stand-alone execution rather than offloading ๐-moptimizeโ Applies partitioned execution optimizations โญ This is on by default whenever any level of optimization is selected ๐-msoft-stackโ Generates code that doesn't use.localmemory directly for stack storage. Instead, a per-warp stack pointer gets maintained explicitly ๐ฆ This unlocks variable-length stack allocation (with variable-length arrays oralloca). When global memory is the underlying storage, it also makes it possible to access automatic variables from other threads, or with atomic instructions ๐ญ This codegen variant is used for OpenMP offloading, but the option is exposed on its own so you can test the compiler. To generate code suitable for linking into programs that use OpenMP offloading, use-mgompinstead ๐ซถ-muniform-simtโ Switches to a codegen variant that lets every thread in each warp execute, while memory state and side effects still look like only one thread per warp was active outside of OpenMP SIMD regions ๐ฅ All atomic operations and calls to runtime functions (malloc,free,vprintf) are conditionally executed (iff the current lane index equals the master lane index). The register being assigned gets copied from the master lane via a shuffle instruction ๐ Outside of SIMD regions, lane 0 is the master. Inside them, each thread sees itself as the master ๐ธ A shared memory arrayint __nvptx_uni[]stores all-zeros or all-ones bitmasks for each warp, showing the current mode (0 outside of SIMD regions) โจ Each thread can bitwise-and the bitmask at positiontid.ywith the current lane index to work out the master lane index ๐ง-mgompโ Generates code for OpenMP offloading ๐ This enables-msoft-stackand-muniform-simt, and selects the matching multilib variant ๐
๐ธ OpenRISC Options ๐ธ
These options are defined for OpenRISC ๐ง
-mboard=nameโ Configures a board-specific runtime ๐ This gets passed to the linker for newlib board library linking. The default isor1ksim๐-mnewlibโ This option is ignored and only exists for compatibility purposes ๐ It used to select linker and preprocessor options for use with newlib-msoft-div,-mhard-divโ Selects software or hardware divide (l.div,l.divu) instructions. This default is hardware divide ๐ฆ-msoft-mul,-mhard-mulโ Selects software or hardware multiply (l.mul,l.muli) instructions. This default is hardware multiply ๐-msoft-float,-mhard-floatโ Selects software or hardware for floating point operations. The default is software ๐ซถ-mdouble-floatโ When-mhard-floatis selected, this enables generation of double-precision floating point instructions ๐ By default, functions from libgcc handle double-precision floating point operations ๐ง-munordered-floatโ When-mhard-floatis selected, this enables generation of unordered floating point compare and set flag (lf.sfun*) instructions โจ By default, functions from libgcc handle unordered floating point compare and set flag operations ๐-mcmovโ Enables generation of conditional move (l.cmov) instructions ๐ By default, the equivalent gets generated using set and branch ๐ฆ-mrorโ Enables generation of rotate right (l.ror) instructions ๐ฅ By default, functions from libgcc handle rotate right operations ๐-mroriโ Enables generation of rotate right with immediate (l.rori) instructions ๐ธ By default, functions from libgcc handle rotate right with immediate operations ๐-msextโ Enables generation of sign extension (l.ext*) instructions โญ By default, memory loads are used to do sign extension ๐-msfimmโ Enables generation of compare and set flag with immediate (l.sf*i) instructions ๐ By default, extra instructions get generated to store the immediate in a register first ๐ญ-mshftimmโ Enables generation of shift with immediate (l.srai,l.srli,l.slli) instructions ๐ง By default, extra instructions get generated to store the immediate in a register first ๐ซถ
โจ PDP-11 Options โจ
These options are defined for the PDP-11 ๐
-mfpuโ Uses hardware FPP floating point, and this is the default ๐ (FIS floating point on the PDP-11/40 isn't supported.) Implies-m45๐-msoft-floatโ Doesn't use hardware floating point ๐-mac0โ Returns floating-point results inac0(fr0in Unix assembler syntax) ๐ฆ-mno-ac0โ Returns floating-point results in memory. This is the default ๐-m40โ Generates code for a PDP-11/40. Implies-msoft-float -mno-split๐ฅ-m45โ Generates code for a PDP-11/45. This is the default ๐-m10โ Generates code for a PDP-11/10. Implies-msoft-float -mno-splitโจ-mint16,-mno-int32โ Uses 16-bitint. This is the default ๐ธ-mint32,-mno-int16โ Uses 32-bitint๐ง-msplitโ The target has split instruction and data space. Implies-m45๐-munix-asmโ Uses Unix assembler syntax ๐ซถ-mdec-asmโ Uses DEC assembler syntax ๐-mgnu-asmโ Uses GNU assembler syntax. This is the default ๐-mlraโ Uses the new LRA register allocator ๐ By default, the oldreloadallocator is used ๐ญ
๐ง picoChip Options ๐ง
These -m options are defined for picoChip implementations ๐
-mae=ae_typeโ Sets the instruction set, register set, and instruction scheduling parameters for array element typeae_type. Supported values forae_typeareANY,MUL, andMACโจ-mae=ANYโ Selects a completely generic AE type ๐ Code generated with this option runs on any of the other AE types ๐ง It isn't as efficient as code compiled for a specific AE type, and some operations (e.g., multiplication) don't work properly on every type of AE ๐-mae=MULโ Selects a MUL AE type. This is the most useful AE type for compiled code, and it's the default ๐-mae=MACโ Selects a DSP-style MAC AE ๐ฅ Code compiled with this option may suffer from poor performance of byte (char) manipulation, since the DSP AE doesn't have hardware support for byte load/stores ๐ญ
-msymbol-as-addressโ Lets the compiler use a symbol name directly as an address in a load/store instruction, without loading it into a register first ๐ฆ This usually makes programs larger but faster, though results vary from program to program ๐ซถ That's why it's left as a user option instead of being permanently enabled ๐-mno-inefficient-warningsโ Disables warnings about generating inefficient code ๐ These warnings can show up when you compile code doing byte-level memory operations on the MAC AE type. The MAC AE has no hardware support for byte-level memory operations, so every byte load/store has to be synthesized from word load/store operations ๐ That's inefficient, so GCC warns you to rewrite the code to avoid byte operations, or to target an AE type with the right hardware support. This option turns those warnings off ๐ธ
๐ PowerPC Options ๐
These are listed under ๐
๐ PRU Options ๐
These command-line options are defined for the PRU target ๐
-minrtโ Links with a minimum runtime environment, with no support for static initializers and constructors ๐ง Using this can significantly shrink the final ELF binary ๐
Beware! The compiler could still generate code with static initializers and constructors. It's up to you, the programmer, to make sure your source program won't use those features ๐
-mmcu=mcuโ Specifies the PRU MCU variant to use. Check Newlib for the exact list of supported MCUs ๐ฅ-mno-relaxโ Makes GCC pass the--no-relaxcommand-line option to the linker instead of--relax๐ฆ-mloopโ Allows (or doesn't allow) GCC to use the LOOP instruction โจ-mabi=variantโ Specifies the ABI variant to output code for.-mabi=tiselects the unmodified TI ABI, while-mabi=gnuselects a GNU variant that copes more naturally with certain GCC assumptions ๐ These are the differences:- Function Pointer Size โ TI ABI specifies that function (code) pointers are 16-bit, whereas GNU supports only 32-bit data and code pointers ๐
- Optional Return Value Pointer โ Function return values larger than 64 bits get passed using a hidden pointer as the first argument of the function. TI ABI, though, mandates that the pointer can be NULL in case the caller isn't using the returned value. GNU always passes and expects a valid return value pointer ๐ซถ
The current-mabi=tiimplementation simply raises a compile error when any of the above code constructs is detected. As a consequence, the standard C library can't be built, and it's omitted when linking with-mabi=ti๐ญ
Okay so the TI relaxation thing is a whole vibe check ๐ relaxation is a GNU feature, and for safety reasons it's switched off when you use -mabi=ti ๐
. The TI toolchain doesn't emit relocations for QBBx instructions, so the GNU linker can't adjust them when it shortens the adjacent LDI32 pseudo instructions. Not the vibe ๐
๐ฆ RISC-V Options ๐ฆ
These are the RISC-V flags ๐ง (only for RISC-V targets, so no mixing them up, bestie):
-mbranch-cost=nโ sets the cost of branches to roughlyninstructions โจ-mplt,-mno-pltโ when you're making PIC code, these decide whether PLTs are allowed (-mplt) or kept out (-mno-plt) ๐ธ. They're ignored for non-PIC. The default is-mplt.-mabi=ABI-stringโ this picks the integer and floating-point calling convention ๐. The ABI-string has two parts: the size of integer types, and which registers get used for floating-point types. For example,-march=rv64ifd -mabi=lp64dmeanslongand pointers are 64-bit (sointis implicitly 32-bit), and floating-point values up to 64 bits wide get passed in F registers ๐ฅ.- Compare that with
-march=rv64ifd -mabi=lp64f๐. The compiler can still generate code that uses the F and D extensions, but only floating-point values up to 32 bits long get passed in registers. - Or
-march=rv64ifd -mabi=lp64, where no floating-point arguments get passed in registers at all. - The default is system dependent, so if you want a specific calling convention, specify one explicitly ๐ซถ.
- The valid calling conventions are
ilp32,ilp32f,ilp32d,lp64,lp64f, andlp64d. - Some conventions are impossible on some ISAs. For example,
-march=rv32if -mabi=ilp32dis invalid, because the ABI requires 64-bit values to be passed in F registers, but F registers are only 32 bits wide ๐. - There's also the
ilp32eABI, which can only be used with therv32earchitecture. It's not well specified at present and is subject to change.
- Compare that with
-mfdiv,-mno-fdivโ do or don't use hardware floating-point divide and square root instructions ๐งฎ. This needs the F or D extensions for floating-point registers. The default is to use them if the specified architecture has these instructions.-mdiv,-mno-divโ do or don't use hardware instructions for integer division โ. This needs the M extension. The default is to use them if the specified architecture has these instructions.-march=ISA-stringโ generates code for the given RISC-V ISA (e.g.rv64im) ๐. ISA strings must be lower-case. Examples includerv64i,rv32g,rv32e, andrv32imaf.-mtune=processor-stringโ optimizes the output for the given processor, specified by microarchitecture name ๐. The permissible values arerocket,sifive-3-series,sifive-5-series,sifive-7-series, andsize.- When
-mtune=isn't specified, the default isrocket. - The
sizechoice isn't meant for end-users ๐. It's used when-Osis specified, and it overrides the instruction cost info provided by-mtune=, but it does not override the pipeline info. This helps reduce code size while still giving good performance.
- When
-mpreferred-stack-boundary=numโ attempts to keep the stack boundary aligned to a 2 raised to num byte boundary ๐. If-mpreferred-stack-boundaryisn't specified, the default is4(16 bytes or 128-bits).
Warning: If you use this switch, then you must build all modules with the same value, including any libraries. This includes the system libraries and startup modules ๐จ.
-msmall-data-limit=nโ puts global and static data smaller thannbytes into a special section (on some targets) ๐งธ.-msave-restore,-mno-save-restoreโ do or don't use smaller but slower prologue and epilogue code that uses library function calls ๐ข. The default is to use fast inline prologues and epilogues โก.-mstrict-align,-mno-strict-alignโ do not or do generate unaligned memory accesses ๐งฑ. The default depends on whether the processor you're optimizing for supports fast unaligned access or not.-mcmodel=medlowโ generates code for the medium-low code model ๐. The program and its statically defined symbols must lie within a single 2 GiB address range, and must lie between absolute addresses -2 GiB and +2 GiB. Programs can be statically or dynamically linked. This is the default code model ๐.-mcmodel=medanyโ generates code for the medium-any code model ๐. The program and its statically defined symbols must be within any single 2 GiB address range. Programs can be statically or dynamically linked.-mexplicit-relocs,-mno-exlicit-relocsโ use or don't use assembler relocation operators when dealing with symbolic addresses ๐. The alternative is to use assembler macros instead, which may limit optimization.-mrelax,-mno-relaxโ takes advantage of linker relaxations to reduce the number of instructions needed to materialize symbol addresses โ๏ธ. The default is to take advantage of linker relaxations.-memit-attribute,-mno-emit-attributeโ emits (or doesn't emit) a RISC-V attribute to record extra information into ELF objects ๐ท๏ธ. This feature requires at least binutils 2.32.-malign-data=typeโ controls how GCC aligns variables and constants of array, structure, or union types ๐. The supported values for type arexlen, which uses the x register width as the alignment value, andnatural, which uses natural alignment.xlenis the default.
๐ธ RL78 Options ๐ธ
-msimโ links in additional target libraries so things can run inside a simulator ๐ฅ๏ธ.-mmul=none,-mmul=g10,-mmul=g13,-mmul=g14,-mmul=rl78โ picks the type of hardware multiplication and division support to use โ๏ธโ. The simplest is"none", which uses software for both multiplication and division, and it's the default. The"g13"value is for the hardware multiply/divide peripheral on the RL78/G13 (S2 core) targets. The"g14"value selects the multiplication and division instructions supported by the RL78/G14 (S3 core) parts ๐. The value"rl78"is an alias for"g14", and the value"mg10"is an alias for"none".- A C preprocessor macro is also defined, based on this setting ๐ง. The possible values are
"__RL78_MUL_NONE__","__RL78_MUL_G13__", or"__RL78_MUL_G14__".
- A C preprocessor macro is also defined, based on this setting ๐ง. The possible values are
-mcpu=g10,-mcpu=g13,-mcpu=g14,-mcpu=rl78โ specifies the RL78 core to target ๐ฏ. The default is the G14 core, also known as an S3 core or just RL78 ๐.- The G13 or S2 core doesn't have multiply or divide instructions. It uses a hardware peripheral for those operations instead.
- The G10 or S1 core doesn't have register banks, so it uses a different calling convention.
- If this option is set, it also selects the type of hardware multiply support to use, unless you override it with an explicit
-mmul=noneoption on the command line. So-mcpu=g13enables the G13 hardware multiply peripheral, and-mcpu=g10disables hardware multiplications altogether ๐ . - Heads up, although the RL78/G14 core is the default target, specifying
-mcpu=g14or-mcpu=rl78on the command line does change the toolchain's behavior, since it also enables G14 hardware multiply support ๐. If these options aren't specified on the command line, software multiplication routines will be used even though the code targets the RL78 core. This is for backwards compatibility with older toolchains that didn't have hardware multiply and divide support ๐ฐ๏ธ. - A C preprocessor macro is also defined based on this setting ๐ง. The possible values are
"__RL78_G10__","__RL78_G13__", or"__RL78_G14__".
-mg10,-mg13,-mg14,-mrl78โ these are aliases for the matching-mcpu=option ๐ซถ. They're here for backwards compatibility.-mallregsโ lets the compiler use all of the available registers ๐. By default, registers"r24..r31"are reserved for interrupt handlers. With this option enabled, they can be used in ordinary functions too ๐.-m64bit-doubles,-m32bit-doublesโ makes the"double"data type 64 bits (-m64bit-doubles) or 32 bits (-m32bit-doubles) in size ๐. The default is-m32bit-doubles.-msave-mduc-in-interrupts,-mno-save-mduc-in-interruptsโ specifies whether interrupt handler functions should preserve the MDUC registers ๐ก๏ธ. This is only necessary if normal code might use the MDUC registers, for example because it does multiplication and division operations. The default is to ignore the MDUC registers, because that makes interrupt handlers faster โก. The target option-mg13needs to be passed for this to work, since this feature is only available on the G13 target (S2 core). The MDUC registers will only be saved if the interrupt handler performs a multiplication or division operation, or if it calls another function.
โจ IBM RS/6000 and PowerPC Options โจ
These -m options are defined for the IBM RS/6000 and PowerPC ๐ฆ:
-mpowerpc-gpopt
-mno-powerpc-gpopt
-mpowerpc-gfxopt
-mno-powerpc-gfxopt
-mpowerpc64
-mno-powerpc64
-mmfcrf
-mno-mfcrf
-mpopcntb
-mno-popcntb
-mpopcntd
-mno-popcntd
-mfprnd
-mno-fprnd
-mcmpb
-mno-cmpb
-mhard-dfp
-mno-hard-dfp
You use these options to specify which instructions are available on the processor you're using ๐
. The default value of these options is determined when GCC is configured. Specifying -mcpu=cpu_type overrides the specification of these options. We recommend using the -mcpu=cpu_type option rather than the options listed above ๐ซถ.
Specifying -mpowerpc-gpopt allows GCC to use the optional PowerPC architecture instructions in the General Purpose group, including floating-point square root ๐ฅ. Specifying -mpowerpc-gfxopt allows GCC to use the optional PowerPC architecture instructions in the Graphics group, including floating-point select ๐ธ.
The -mmfcrf option lets GCC generate the move from condition register field instruction, which is implemented on the POWER4 processor and other processors that support the PowerPC V2.01 architecture. ๐
The -mpopcntb option lets GCC generate the popcount and double-precision FP reciprocal estimate instruction from the POWER5 processor and other processors with the PowerPC V2.02 architecture. ๐ฆ The -mpopcntd option lets GCC generate the popcount instruction from the POWER7 processor and other processors with the PowerPC V2.06 architecture. โจ The -mfprnd option lets GCC generate the FP round to integer instructions from the POWER5+ processor and other processors with the PowerPC V2.03 architecture. ๐ธ The -mcmpb option lets GCC generate the compare bytes instruction from the POWER6 processor and other processors with the PowerPC V2.05 architecture. ๐ซถ And the -mhard-dfp option lets GCC generate the decimal floating-point instructions that show up on some POWER processors. ๐ฅ
The -mpowerpc64 option lets GCC generate the extra 64-bit instructions found in the full PowerPC64 architecture, and it treats GPRs as 64-bit doubleword quantities. ๐ GCC defaults to -mno-powerpc64, so you have to ask for it. ๐
-mcpu=cpu_typeโ this sets the architecture type, register usage, and instruction scheduling parameters for the machine type cpu_type. ๐ The supported values are:
401, 403, 405, 405fp, 440, 440fp, 464, 464fp, 476, 476fp, 505,
601, 602, 603, 603e, 604, 604e, 620, 630, 740, 7400, 7450, 750, 801,
821, 823, 860, 970, 8540, a2, e300c2, e300c3, e500mc, e500mc64,
e5500, e6500, ec603e, G3, G4, G5, titan, power3, power4, power5,
power5+, power6, power6x, power7, power8, power9, power10, powerpc,
powerpc64, powerpc64le, rs64, and native
-mcpu=powerpc, -mcpu=powerpc64, and -mcpu=powerpc64le are the pure, generic options. โญ They give you pure 32-bit PowerPC (either endian), 64-bit big endian PowerPC, and 64-bit little endian PowerPC machine types, with a generic processor model assumed for scheduling. ๐ง
Picking native detects the host processor and selects the matching architecture option. ๐ If GCC doesn't recognize the processor, -mcpu=native does absolutely nothing. ๐
The other values pick one specific processor. ๐ Code built for that chip runs its best on it, and it might not run at all on other chips. ๐ญ
The -mcpu options automatically enable or disable the following options:
-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple -mpopcntb
-mpopcntd -mpowerpc64 -mpowerpc-gpopt -mpowerpc-gfxopt -mmulhw
-mdlmzb -mmfpgpr -mvsx -mcrypto -mhtm -mpower8-fusion
-mpower8-vector -mquad-memory -mquad-memory-atomic -mfloat128
-mfloat128-hardware -mprefixed -mpcrel -mmma
Heads up, the exact set of options for each CPU changes between compiler versions. ๐ It's whatever GCC thinks produces the best code for that CPU, so it doesn't always match what the hardware can actually do. ๐คทโโ๏ธ If you want to set one individual option to a specific value, put it after the -mcpu option, like -mcpu=970 -mno-altivec. ๐
On AIX,-maltivecand-mpowerpc64are not enabled or disabled by the-mcpuoption right now, because AIX doesn't have full support for these options. ๐จ You can still turn them on or off individually, but only if you're sure it'll work in your environment.
-mtune=cpu_typeโ this sets the instruction scheduling parameters for the machine type cpu_type, but it does NOT touch the architecture type or register usage the way-mcpu=cpu_typedoes. ๐ฏ It takes the samecpu_typevalues as-mcpu. If you specify both, the code uses the architecture and registers from-mcpu, but the scheduling parameters from-mtune. ๐ซถ-mcmodel=smallโ this generates PowerPC64 code for the small model, where the TOC is limited to 64k. ๐-mcmodel=mediumโ this generates PowerPC64 code for the medium model, where the TOC and other static data can total up to 4G in size. โจ This is the default for 64-bit Linux. ๐ง-mcmodel=largeโ this generates PowerPC64 code for the large model, where the TOC can be up to 4G in size. ๐ Other data and code are only limited by the 64-bit address space. ๐-maltivec,-mno-altivecโ these generate code that does (or doesn't) use AltiVec instructions, and they also turn on built-in functions that give you more direct access to the AltiVec instruction set. ๐ You might also need to set-mabi=altivecto adjust the current ABI with AltiVec ABI enhancements. ๐ฆ
When -maltivec is in use, the element order for AltiVec intrinsics like "vec_splat", "vec_extract", and "vec_insert" matches the array element order for the target's endianness. ๐ง So element zero is the leftmost element in a vector register on a big-endian target, and it's the rightmost element in a vector register on a little-endian target. ๐ธ
-mvrsave,-mno-vrsaveโ these generate VRSAVE instructions when generating AltiVec code. ๐-msecure-pltโ this generates code that letsldandld.sobuild executables and shared libraries with non-executable".plt"and".got"sections. ๐ It's a PowerPC 32-bit SYSV ABI option. ๐-mbss-pltโ this generates code that uses a BSS".plt"section thatld.sofills in. ๐งฉ It needs".plt"and".got"sections that are both writable AND executable, so be careful with it. โ ๏ธ It's also a PowerPC 32-bit SYSV ABI option. ๐-misel,-mno-iselโ this switch enables or disables the generation of ISEL instructions. ๐-mvsx,-mno-vsxโ these generate code that does (or doesn't) use vector/scalar (VSX) instructions, and they turn on built-in functions for more direct access to the VSX instruction set. ๐ฅ-mcrypto,-mno-cryptoโ these enable (or disable) the built-in functions that give direct access to the cryptographic instructions added in version 2.07 of the PowerPC ISA. ๐-mhtm,-mno-htmโ these enable (or disable) the built-in functions for direct access to the Hardware Transactional Memory (HTM) instructions added in version 2.07 of the PowerPC ISA. ๐ง-mpower8-fusion,-mno-power8-fusionโ these generate code that keeps some integer operations next to each other, so the instructions can be fused together on POWER8 and later processors. ๐งฒ With-mno-power8-fusion, that adjacency isn't kept. ๐ โโ๏ธ-mpower8-vector,-mno-power8-vectorโ these generate code that does (or doesn't) use the vector and scalar instructions added in version 2.07 of the PowerPC ISA. ๐ They also turn on built-in functions for more direct access to the vector instructions. ๐-mquad-memory,-mno-quad-memoryโ these generate code that does (or doesn't) use the non-atomic quad word memory instructions. ๐ The-mquad-memoryoption requires 64-bit mode. ๐ฅ๏ธ-mquad-memory-atomic,-mno-quad-memory-atomicโ these generate code that does (or doesn't) use the atomic quad word memory instructions. โ๏ธ The-mquad-memory-atomicoption also requires 64-bit mode. ๐ฅ๏ธ-mfloat128,-mno-float128โ these enable or disable the__float128keyword for IEEE 128-bit floating point. ๐ They also choose between software emulation or hardware instructions for IEEE 128-bit floating point. ๐งช
You have to enable the VSX instruction set (-mvsx) to use the IEEE 128-bit floating point support. ๐ซ And the IEEE 128-bit floating point support is only supported on Linux. ๐ง
By default, -mfloat128 is enabled on PowerPC Linux systems that use the VSX instruction set, and it's disabled on other systems. โจ
If you use the ISA 3.0 instruction set (-mpower9-vector or -mcpu=power9) on a 64-bit system, the IEEE 128-bit floating point support also turns on the generation of ISA 3.0 IEEE 128-bit floating point instructions. ๐ Otherwise, if you don't ask for ISA 3.0 instructions, or you're targeting a 32-bit big endian system, IEEE 128-bit floating point gets done with software emulation. ๐ข
-mfloat128-hardware,-mno-float128-hardwareโ these enable (or disable) using ISA 3.0 hardware instructions to support the__float128data type. ๐ ๏ธ
By default, -mfloat128-hardware is enabled on PowerPC Linux systems that use the ISA 3.0 instruction set, and it's disabled on other systems. ๐
-m32,-m64โ these generate code for 32-bit or 64-bit environments on Darwin and SVR4 targets (including GNU/Linux). ๐ The 32-bit environment setsint,long, and pointer to 32 bits, and it generates code that runs on any PowerPC variant. ๐ซ The 64-bit environment setsintto 32 bits, setslongand pointer to 64 bits, and generates code for PowerPC64, just like-mpowerpc64. ๐ง-mfull-toc,-mno-fp-in-toc,-mno-sum-in-toc,-mminimal-tocโ these modify how the TOC (Table Of Contents) is generated, and every executable file gets one. ๐ The-mfull-tocoption is selected by default. ๐ In that case, GCC allocates at least one TOC entry for each unique non-automatic variable reference in your program, and it also puts floating-point constants in the TOC. ๐งพ The catch is that only 16,384 entries are available in the TOC. ๐ฌ
If you get a linker error message saying you've overflowed the available TOC space, you can shrink the TOC usage with -mno-fp-in-toc and -mno-sum-in-toc. ๐ -mno-fp-in-toc stops GCC from putting floating-point constants in the TOC. -mno-sum-in-toc makes GCC generate code that calculates the sum of an address and a constant at run time, instead of stuffing that sum into the TOC. ๐งฎ You can use one or both of these options. Each one makes the code very slightly slower and larger, but it saves TOC space. ๐
If you're STILL out of TOC space even with both of those options, use -mminimal-toc instead. ๐ค This option makes GCC create only one TOC entry for every file. ๐ The code gets slower and larger, but it uses extremely little TOC space. ๐ You might want to use this option only on files with less frequently-executed code. ๐ง
-maix64,-maix32โ okay bestie,-maix64turns on the 64-bit AIX ABI and calling convention ๐ so you get 64-bit pointers, a 64-bit "long" type, and all the infrastructure needed to make them work โจ.-maix64also implies-mpowerpc64.-maix32goes the other way and disables the 64-bit ABI, implying-mno-powerpc64. GCC defaults to-maix32๐-mxl-compat,-mno-xl-compatโ this one makes your code act more like IBM XL compiler output when you're using the AIX-compatible ABI ๐ฆ It passes floating-point arguments to prototyped functions beyond the register save area (RSA) on the stack, in addition to argument FPRs. It also stops assuming that the most significant double in a 128-bitlong doublevalue is properly rounded when comparing values and converting todouble. And it uses XL symbol names for thelong doublesupport routines ๐
The AIX calling convention got extended, but that wasn't documented at first, all to handle an obscure K&R C case: calling a function that takes the address of its arguments with fewer arguments than it declared. IBM XL compilers read floating-point arguments that don't fit in the RSA from the stack when a subroutine is compiled without optimization. Always storing floating-point arguments on the stack is inefficient and rarely needed, so this option is not on by default. You only need it when calling subroutines compiled by IBM XL compilers without optimization ๐
-mpeโ supports the IBM RS/6000 SP Parallel Environment (PE) ๐ It links an application that uses message passing with special startup code so it can actually run. Your system needs PE installed in the standard location (/usr/lpp/ppe.poe/). Otherwise, you have to override the specs file with-specs=to point at the right directory location โจ
The Parallel Environment doesn't support threads, so-mpeand-pthreadare incompatible. Don't mix them, bestie ๐
-malign-natural,-malign-powerโ on AIX, 32-bit Darwin, and 64-bit PowerPC GNU/Linux,-malign-naturaloverrides the ABI-defined alignment of bigger types (like floating-point doubles) and puts them on their natural size-based boundary ๐-malign-powertells GCC to follow the ABI-specified alignment rules instead. GCC defaults to the standard alignment from the ABI ๐
On 64-bit Darwin, natural alignment is already the default, and -malign-power is not supported there ๐
-msoft-float,-mhard-floatโ-msoft-floatmakes the code skip the floating-point register set, so you get software floating-point emulation. You have to pass the option to GCC when linking too ๐ซถ-mhard-floatis the opposite: the code does use the floating-point register set ๐ฅ-mmultiple,-mno-multipleโ-mmultiplegenerates code that uses the load multiple word and store multiple word instructions, and-mno-multiplesays "nah, skip those." These instructions are generated by default on POWER systems and not on PowerPC systems ๐ธ
Don't use -mmultiple on little-endian PowerPC systems, since those instructions don't work when the processor is in little-endian mode. The exceptions are PPC740 and PPC750, which permit them in little-endian mode ๐
-mupdate,-mno-updateโ-mupdatelets the code use load or store instructions that update the base register to the address of the calculated memory location. These are generated by default.-mno-updateopts out of them โจ
If you use -mno-update, there's a small window between when the stack pointer gets updated and when the address of the previous frame gets stored. That means code that walks the stack frame across interrupts or signals may end up with corrupted data ๐ญ
-mavoid-indexed-addresses,-mno-avoid-indexed-addressesโ-mavoid-indexed-addressestries to avoid indexed load or store instructions, and-mno-avoid-indexed-addresseslets them be used ๐ง Indexed instructions can cost you performance on Power6 processors in certain situations, like stepping through large arrays that cross a 16M boundary. This option is enabled by default when targeting Power6 and disabled otherwise ๐ฆ-mfused-madd,-mno-fused-maddโ-mfused-maddgenerates code that uses the floating-point multiply and accumulate instructions.-mno-fused-maddskips them. These are generated by default if hardware floating point is used ๐ Fun plot twist: the machine-dependent-mfused-maddis now mapped to the machine-independent-ffp-contract=fast, and-mno-fused-maddis mapped to-ffp-contract=off๐-mmulhw,-mno-mulhwโ-mmulhwuses the half-word multiply and multiply-accumulate instructions on the IBM 405, 440, 464 and 476 processors, while-mno-mulhwdoes not. These instructions are generated by default when targeting those processors โญ-mdlmzb,-mno-dlmzbโ-mdlmzbuses the string-searchdlmzbinstruction on the IBM 405, 440, 464 and 476 processors, and-mno-dlmzbdoesn't. This instruction is generated by default when targeting those processors ๐
-mno-bit-align,-mbit-alignโ on System V.4 and embedded PowerPC systems,-mno-bit-aligndoes not force structures and unions containing bit-fields to be aligned to the base type of the bit-field, and-mbit-aligndoes ๐
Like, by default a structure containing nothing but 8 unsigned bit-fields of length 1 is aligned to a 4-byte boundary and has a size of 4 bytes ๐ Use -mno-bit-align and that same structure is aligned to a 1-byte boundary and is only 1 byte in size. Iconic glow-up ๐
-mno-strict-align,-mstrict-alignโ on System V.4 and embedded PowerPC systems,-mno-strict-aligndoes not assume that unaligned memory references are handled by the system.-mstrict-aligndoes make that assumption ๐ซถ-mrelocatable,-mno-relocatableโ-mrelocatablegenerates code that lets a static executable be relocated to a different address at run time.-mno-relocatabledoes not allow that ๐ง A simple embedded PowerPC system loader should relocate the entire contents of.got2and the 4-byte locations listed in the.fixupsection, which is a table of 32-bit addresses this option generates. For this to work, every object you link together must be compiled with-mrelocatableor-mrelocatable-lib. Also,-mrelocatablecode aligns the stack to an 8-byte boundary ๐-mrelocatable-lib,-mno-relocatable-libโ like-mrelocatable,-mrelocatable-libgenerates a.fixupsection so static executables can be relocated at run time. The difference is that it does not use the smaller stack alignment that-mrelocatableuses ๐ธ Objects compiled with-mrelocatable-libcan be linked with objects compiled with any combination of the-mrelocatableoptions ๐ฆ-mno-toc,-mtocโ on System V.4 and embedded PowerPC systems,-mno-tocdoes not assume that register 2 holds a pointer to a global area with the addresses used in the program.-mtocdoes assume that ๐-mlittle,-mlittle-endianโ on System V.4 and embedded PowerPC systems, this compiles code for the processor in little-endian mode ๐-mlittle-endianis the same as-mlittleโจ-mbig,-mbig-endianโ on System V.4 and embedded PowerPC systems, this compiles code for the processor in big-endian mode ๐-mbig-endianis the same as-mbig๐-mdynamic-no-picโ on Darwin and Mac OS X systems, this compiles code so it is not relocatable, but its external references are relocatable ๐ฅ The result is good for applications, but not shared libraries ๐ โโ๏ธ-msingle-pic-baseโ treats the register used for PIC addressing as read-only, instead of loading it in the prologue for each function ๐ The runtime system is responsible for initializing this register with an appropriate value before execution begins ๐ง-mprioritize-restricted-insns=priorityโ controls the priority given to dispatch-slot restricted instructions during the second scheduling pass โญ The argumentprioritytakes the value0,1, or2, which assigns no, highest, or second-highest priority to dispatch-slot restricted instructions, respectively ๐-msched-costly-dep=dependence_typeโ controls which dependences the target considers costly during instruction scheduling ๐ฆ The argumentdependence_typetakes one of these values:noโ no dependence is costly ๐allโ all dependences are costly ๐ฅtrue_store_to_loadโ a true dependence from store to load is costly ๐ธstore_to_loadโ any dependence from store to load is costly ๐ซถnumberโ any dependence whose latency is greater than or equal tonumberis costly โจ
-minsert-sched-nops=schemeโ controls which NOP insertion scheme gets used during the second scheduling pass ๐ The argumentschemetakes one of these values:noโ don't insert NOPs ๐padโ pad with NOPs any dispatch group that has vacant issue slots, according to the scheduler's grouping ๐งregroup_exactโ insert NOPs to force costly dependent insns into separate groups. It inserts exactly as many NOPs as needed to push an insn into a new group, according to the estimated processor grouping ๐numberโ insert NOPs to force costly dependent insns into separate groups. It insertsnumberNOPs to force an insn into a new group ๐
-mcall-sysvโ on System V.4 and embedded PowerPC systems, compiles code using calling conventions that follow the March 1995 draft of the System V Application Binary Interface, PowerPC processor supplement ๐ This is the default unless you configured GCC usingpowerpc-*-eabiaix๐-mcall-sysv-eabi,-mcall-eabiโ specifies both-mcall-sysvand-meabi๐-mcall-sysv-noeabiโ specifies both-mcall-sysvand-mno-eabi๐ซถ-mcall-aixdescโ on System V.4 and embedded PowerPC systems, compiles code for the AIX operating system ๐ฆ-mcall-linuxโ on System V.4 and embedded PowerPC systems, compiles code for the Linux-based GNU system ๐ง-mcall-freebsdโ on System V.4 and embedded PowerPC systems, compiles code for the FreeBSD operating system ๐-mcall-netbsdโ on System V.4 and embedded PowerPC systems, compiles code for the NetBSD operating system ๐ธ-mcall-openbsdโ on System V.4 and embedded PowerPC systems, compiles code for the OpenBSD operating system โจ-mtraceback=traceback_typeโ selects the type of traceback table ๐ง Valid values fortraceback_typearefull,part, andno๐-maix-struct-returnโ returns all structures in memory, as the AIX ABI specifies ๐-msvr4-struct-returnโ returns structures smaller than 8 bytes in registers, as the SVR4 ABI specifies ๐-mabi=abi-typeโ ๐ Glow up your ABI with an extension, or drop one you don't need. The valid picks arealtivec,no-altivec,ibmlongdouble,ieeelongdouble,elfv1, andelfv2. On AIX you also getvec-extabiandvec-defaultโจ-mabi=ibmlongdoubleโ ๐ Switches the ABI to IBM extended-precisionlong double. Bestie, this is not likely to work if your system defaults to IEEE extended-precisionlong double. If you switch away from IEEE extended-precision, the compiler will warn you unless you add-Wno-psabi. You also need-mlong-double-128turned on.-mabi=ieeelongdoubleโ ๐ธ Switches the ABI to IEEE extended-precisionlong double. Same tea here: it's not likely to work if your system defaults to IBM extended-precisionlong double. Switching away from IBM extended-precision gets you a warning unless you use-Wno-psabi. This one also requires-mlong-double-128to be enabled.-mabi=elfv1โ ๐ง Changes the ABI to ELFv1. This is the default for big-endian PowerPC 64-bit Linux. Overriding the default needs special system support and is likely to fail in spectacular ways ๐-mabi=elfv2โ ๐ฆ Changes the ABI to ELFv2. This is the default for little-endian PowerPC 64-bit Linux. Overriding the default also needs special system support and is likely to fail in spectacular ways ๐ญ-mgnu-attribute,-mno-gnu-attributeโ ๐ Emits.gnu_attributeassembly directives that set tag/value pairs in a.gnu.attributessection. These describe the ABI variations for function parameters or return values.-mprototype,-mno-prototypeโ ๐ On System V.4 and embedded PowerPC, this tells the compiler to assume every call to a variable argument function is properly prototyped. Without it, the compiler has to slip in an instruction before every non-prototyped call to set or clear bit 6 of the condition code register (CR). That bit tells the function whether floating-point values are passed in the floating-point registers, in case it takes variable arguments. With-mprototype, only calls to prototyped variable argument functions set or clear that bit.-msimโ ๐ On embedded PowerPC, this assumes the startup module issim-crt0.oand the standard C libraries arelibsim.aandlibc.a. It's the default forpowerpc-*-eabisimconfigurations.-mmvmeโ ๐ On embedded PowerPC, this assumes the startup module iscrt0.oand the standard C libraries arelibmvme.aandlibc.a.-madsโ โญ On embedded PowerPC, this assumes the startup module iscrt0.oand the standard C libraries arelibads.aandlibc.a.-myellowknifeโ ๐ On embedded PowerPC, this assumes the startup module iscrt0.oand the standard C libraries arelibyk.aandlibc.a.-mvxworksโ ๐ฅ On System V.4 and embedded PowerPC, this tells GCC you're compiling for a VxWorks system.-membโ ๐ซถ On embedded PowerPC, this sets thePPC_EMBbit in the ELF flags header, which indicates that eabi extended relocations are used.-meabi,-mno-eabiโ ๐ธ On System V.4 and embedded PowerPC,-meabimakes the compiler adhere to the Embedded Applications Binary Interface (EABI), a set of tweaks to the System V.4 specs.-mno-eabimeans it does not. With-meabi, the stack is aligned to an 8-byte boundary, a function__eabiis called frommainto set up the EABI environment, and the-msdataoption can use bothr2andr13to point to two separate small data areas. With-mno-eabi, the stack is aligned to a 16-byte boundary, no EABI initialization function is called frommain, and-msdataonly usesr13to point to a single small data area.-meabiis on by default if you configured GCC with one of thepowerpc*-*-eabi*options.-msdata=eabiโ ๐ฆ On System V.4 and embedded PowerPC, small initializedconstglobal and static data goes in the.sdata2section, pointed to by registerr2. Small initialized non-constglobal and static data goes in the.sdatasection, pointed to by registerr13. Small uninitialized global and static data goes in the.sbsssection, which sits right next to.sdata. This option is incompatible with-mrelocatable, and it also sets-memb.-msdata=sysvโ ๐ง On System V.4 and embedded PowerPC, small global and static data goes in the.sdatasection, pointed to by registerr13. Small uninitialized global and static data goes in the.sbsssection, next to.sdata. This option is incompatible with-mrelocatable.-msdata=default,-msdataโ ๐ On System V.4 and embedded PowerPC, if-meabiis used, the code compiles the same as-msdata=eabi. Otherwise, it compiles the same as-msdata=sysv.-msdata=dataโ ๐ On System V.4 and embedded PowerPC, small global data goes in the.sdatasection, and small uninitialized global data goes in the.sbsssection. The one difference: registerr13is not used to address small data. This is the default unless other-msdataoptions are used.-msdata=none,-mno-sdataโ ๐ On embedded PowerPC, all initialized global and static data goes in the.datasection, and all uninitialized data goes in the.bsssection.-mreadonly-in-sdataโ ๐ Puts read-only objects in the.sdatasection too. This is the default.-mblock-move-inline-limit=numโ โจ Inlines all block moves (like calls tomemcpyor structure copies) that are less than or equal tonumbytes. The minimum value fornumis 32 bytes on 32-bit targets and 64 bytes on 64-bit targets. The default is target-specific.-mblock-compare-inline-limit=numโ ๐ฅ Generates non-looping inline code for all block compares (like calls tomemcmpor structure compares) that are less than or equal tonumbytes. Ifnumis0, all inline expansion of block compare, both non-loop and loop, is disabled. The default is target-specific.-mblock-compare-inline-loop-limit=numโ ๐ Generates an inline expansion using loop code for all block compares that are less than or equal tonumbytes but greater than the limit for non-loop inline block compare expansion. If the block length isn't constant, at mostnumbytes get compared beforememcmpis called to compare the rest of the block. The default is target-specific.-mstring-compare-inline-limit=numโ ๐ฆ Compares at mostnumstring bytes with inline code. If the difference or end of string isn't found by the end of the inline compare, a call tostrcmporstrncmptakes care of the rest. The default is 64 bytes.-G numโ ๐ธ On embedded PowerPC, puts global and static items less than or equal tonumbytes into the small data or BSS sections, instead of the normal data or BSS section. By default,numis 8. The-G numswitch also gets passed to the linker, so all modules should be compiled with the same-G numvalue ๐-mregnames,-mno-regnamesโ ๐ซถ On System V.4 and embedded PowerPC, this makes the compiler emit (or not emit) register names in the assembly output using symbolic forms.-mlongcall,-mno-longcallโ ๐ By default, GCC assumes every call is far away, so it uses a longer, more expensive calling sequence. That's required for calls farther than 32 megabytes (33,554,432 bytes) from the current location. A short call is generated when the compiler knows the call can't be that far away. You can override this with theshortcallfunction attribute, or with#pragma longcall(0).
Some linkers can detect out-of-range calls and generate glue code on the fly. On those systems, long calls are unnecessary and generate slower code. As of this writing, the AIX linker can do this, and so can the GNU linker for PowerPC/64. There are plans to add this feature to the GNU linker for 32-bit PowerPC systems too ๐
On PowerPC64 ELFv2 and 32-bit PowerPC systems with newer GNU linkers, GCC can generate long calls using an inline PLT call sequence (see -mpltseq). PowerPC with -mbss-plt and PowerPC64 ELFv1 (big-endian) do not support inline PLT calls ๐
On Darwin/PPC systems, #pragma longcall generates jbsr callee, L42, plus a branch island (glue code). The two target addresses represent the callee and the branch island. The Darwin/PPC linker prefers the first address and generates bl callee if the PPC bl instruction reaches the callee directly. Otherwise, the linker generates bl L42 to call the branch island. The branch island gets appended to the body of the calling function, and it computes the full 32-bit address of the callee and jumps to it ๐ง
On Mach-O (Darwin) systems, this option directs the compiler to emit the glue for every direct call, and the Darwin linker decides whether to use it or discard it ๐ฆ
In the future, GCC may ignore all longcall specifications when the linker is known to generate glue โจ
-mpltseq,-mno-pltseqโ ๐ Implements (or doesn't implement)-fno-pltand long calls using an inline PLT call sequence. That sequence supports lazy linking and long calls to functions indlopen'dshared libraries. Inline PLT calls are only supported on PowerPC64 ELFv2 and on 32-bit PowerPC systems with newer GNU linkers. They're enabled by default if support is detected when configuring GCC, and, in the case of 32-bit PowerPC, if GCC is configured with--enable-secureplt. Be careful, bestie:-mpltseqcode and-mbss-plt32-bit PowerPC relocatable objects may not be linked together ๐ฌ-mtls-markers,-mno-tls-markersโ ๐ฅ Marks (or doesn't mark) calls to__tls_get_addrwith a relocation that specifies the function argument. That relocation lets the linker reliably connect the function call with its argument setup instructions for TLS optimization. That in turn lets GCC schedule the sequence better ๐ซถ
๐ Precision Stuff (Part 2) ๐
Okay so bestie, -mrecip and -mno-recip are giving precision drama ๐
โจ Turning -mrecip on lets the compiler use the reciprocal estimate and reciprocal square root estimate instructions, plus extra Newton-Raphson steps to boost precision, instead of doing a divide or a square root and divide for floating-point arguments ๐ฆ
You should pair it with -ffast-math ๐ฅ (or at least -funsafe-math-optimizations, -ffinite-math-only, -freciprocal-math and -fno-trapping-math) when you use -mrecip. Lowkey non-negotiable ๐ The sequence usually has higher throughput than the non-reciprocal instruction, but the precision can drop by up to 2 ulp ๐ญ (like, the inverse of 1.0 comes out as 0.99999994) for reciprocal square roots.
-mrecip,-mno-recipโ turns the estimate-plus-Newton-Raphson trick on or off, as described above.-mrecip=optโ picks exactly which reciprocal estimate instructions are allowed.optis a comma-separated list, and you can put a"!"in front of any option to invert it. The choices are:allโ enables all estimate instructions.defaultโ enables the default instructions, same as-mrecip.noneโ disables all estimate instructions, same as-mno-recip.divโ enables the reciprocal approximation instructions for both single and double precision.divfโ enables the single-precision reciprocal approximation instructions.divdโ enables the double-precision reciprocal approximation instructions.rsqrtโ enables the reciprocal square root approximation instructions for both single and double precision.rsqrtfโ enables the single-precision reciprocal square root approximation instructions.rsqrtdโ enables the double-precision reciprocal square root approximation instructions.
So, for example, -mrecip=all,!rsqrtd enables all of the reciprocal estimate instructions, except for the "FRSQRTE", "XSRSQRTEDP", and "XVRSQRTEDP" instructions, which handle the double-precision reciprocal square root calculations ๐ง
-mrecip-precision,-mno-recip-precisionโ tells GCC to assume (or not assume) that the reciprocal estimate instructions give you higher precision than the PowerPC ABI requires. Picking-mcpu=power6,-mcpu=power7or-mcpu=power8automatically turns on-mrecip-precisionโจ The double-precision square root estimate instructions are not generated by default on low-precision machines, since they don't converge after three steps ๐-mveclibabi=typeโ chooses the ABI type for vectorizing intrinsics using an external library. The only type supported right now ismass, which tells GCC to use IBM's Mathematical Acceleration Subsystem (MASS) libraries for that job ๐ When generating code for power7, GCC currently emits calls to"acosd2","acosf4","acoshd2","acoshf4","asind2","asinf4","asinhd2","asinhf4","atan2d2","atan2f4","atand2","atanf4","atanhd2","atanhf4","cbrtd2","cbrtf4","cosd2","cosf4","coshd2","coshf4","erfcd2","erfcf4","erfd2","erff4","exp2d2","exp2f4","expd2","expf4","expm1d2","expm1f4","hypotd2","hypotf4","lgammad2","lgammaf4","log10d2","log10f4","log1pd2","log1pf4","log2d2","log2f4","logd2","logf4","powd2","powf4","sind2","sinf4","sinhd2","sinhf4","sqrtd2","sqrtf4","tand2","tanf4","tanhd2", and"tanhf4". Both-ftree-vectorizeand-funsafe-math-optimizationsmust also be enabled, and the MASS libraries must be specified at link time ๐-mfriz,-mno-frizโ generates (or doesn't generate) the"friz"instruction when-funsafe-math-optimizationsis used to optimize rounding floating-point values to 64-bit integers and back to floating point. Heads up:"friz"doesn't return the same value if the floating-point number is too large to fit in an integer ๐ญ-mpointers-to-nested-functions,-mno-pointers-to-nested-functionsโ generates (or doesn't generate) code that loads the static chain register ("r11") when calling through a pointer on AIX and 64-bit Linux systems, where a function pointer points to a 3-word descriptor giving the function address, the TOC value to load into register"r2", and the static chain value to load into register"r11".-mpointers-to-nested-functionsis on by default ๐ธ If you use-mno-pointers-to-nested-functions, you can't call through pointers to nested functions, or through pointers to functions compiled in other languages that use the static chain.-msave-toc-indirect,-mno-save-toc-indirectโ generates (or doesn't generate) code that saves the TOC value in the reserved stack location in the function prologue, if the function calls through a pointer on AIX and 64-bit Linux systems. If the TOC value isn't saved in the prologue, it gets saved just before the call through the pointer.-mno-save-toc-indirectis the default ๐-mcompat-align-parm,-mno-compat-align-parmโ generates (or doesn't generate) code that passes structure parameters with a maximum alignment of 64 bits, for compatibility with older versions of GCC.
Older versions of GCC (prior to 4.9.0) incorrectly didn't align a structure parameter on a 128-bit boundary when that structure had a member requiring 128-bit alignment. This got fixed in more recent versions of GCC. Use this option if you need code that's compatible with functions compiled by older GCC versions ๐ฆ -mno-compat-align-parm is the default.
-mstack-protector-guard=guard,-mstack-protector-guard-reg=reg,-mstack-protector-guard-offset=offset,-mstack-protector-guard-symbol=symbolโ generates stack protection code that uses a canary atguard. The supported locations areglobalfor a global canary, ortlsfor a per-thread canary in the TLS block (the default with GNU libc version 2.4 or later) ๐ก๏ธ
With the tls choice, -mstack-protector-guard-reg=reg and -mstack-protector-guard-offset=offset let you pick which register is the base register for reading the canary, and what offset from that base register to use. The defaults for those come from the relevant ABI. -mstack-protector-guard-symbol=symbol overrides the offset with a symbol reference to a canary in the TLS block โจ
-mpcrel,-mno-pcrelโ generates (or doesn't generate) pc-relative addressing.-mpcrelneeds the medium code model (-mcmodel=medium) and prefixed addressing (-mprefixed) to be enabled too ๐-mprefixed,-mno-prefixedโ generates (or doesn't generate) addressing modes that use prefixed load and store instructions.-mprefixedrequires-mcpu=power10(or later) to be enabled ๐-mmma,-mno-mmaโ generates (or doesn't generate) the MMA instructions. The-mmaoption requires-mcpu=power10(or later) to be enabled ๐
โจ RX Options โจ
These command-line options are defined for RX targets ๐ฆ
-m64bit-doubles,-m32bit-doublesโ makes the"double"data type 64 bits (-m64bit-doubles) or 32 bits (-m32bit-doubles) in size. The default is-m32bit-doubles.
Note: RX floating-point hardware only works on 32-bit values, which is literally why the default is -m32bit-doubles ๐
-fpu,-nofpuโ enables (-fpu) or disables (-nofpu) the use of RX floating-point hardware. It's enabled by default for the RX600 series and disabled for the RX200 series ๐
Floating-point instructions only get generated for 32-bit floating-point values, though, so the FPU hardware isn't used for doubles if -m64bit-doubles is used.
Note: If-fpuis enabled, then-funsafe-math-optimizationsis also enabled automatically. This is because the RX FPU instructions are themselves unsafe ๐
-mcpu=nameโ selects the type of RX CPU to target. Three types are supported right now: the generic RX600 and RX200 series hardware, and the specific RX610 CPU. The default is RX600 ๐
The only difference between RX600 and RX610 is that the RX610 doesn't support the "MVTIPL" instruction.
The RX200 series doesn't have a hardware floating-point unit, so -nofpu is enabled by default when this type is selected.
-mbig-endian-data,-mlittle-endian-dataโ stores data (but not code) in the big-endian format. The default is-mlittle-endian-data, meaning data gets stored in the little-endian format ๐ธ-msmall-data-limit=Nโ specifies the maximum size in bytes of global and static variables that can be placed into the small data area. Using the small data area can lead to smaller and faster code, but the area is limited, and it's up to you to make sure it doesn't overflow ๐ง
When the small data area is used, one of the RX's registers (usually "r13") is reserved to point to this area, so the compiler can't use it anymore. This could result in slower and/or larger code if variables get pushed onto the stack instead of being held in that register.
Heads up: common variables (variables that haven't been initialized) and constants are not placed into the small data area, because they get assigned to other sections in the output executable.
The default value is zero, which disables this feature. This feature isn't enabled by default at higher optimization levels (-O2 etc.) because reserving a register can be detrimental. It's up to you to experiment and figure out whether it benefits your program. See the description of the -mpid option for how the actual register that holds the small data area pointer is chosen ๐
-msim,-mno-simโ uses the simulator runtime. The default is to use the libgloss board-specific runtime ๐-mas100-syntax,-mno-as100-syntaxโ when generating assembler output, uses a syntax compatible with Renesas's AS100 assembler. This syntax can also be handled by the GAS assembler, but it has some restrictions, so it isn't generated by default ๐-mmax-constant-size=N: okay so this caps how big a constant can be (in bytes) when it's used as an operand in an RX instruction ๐ . RX can handle constants up to 4 bytes, but a longer value means a longer instruction, so sometimes it's lowkey smart to restrict the size ๐ง . Anything too big gets tossed into a constant pool and reached through register indirection instead ๐ง.Ncan be between0and4, and both0(the default) and4mean constants of any size are welcome โจ.-mrelax: enables linker relaxation, which is seriously shrink the program energy ๐ฆ. The linker hunts for shorter versions of various instructions to trim your program down. It's disabled by default, so you have to opt in ๐.-mint-register=N: reserves registers for fast interrupt handler functions ๐.Ncan be between0and4. A value of1reservesr13for fast interrupt handlers only,2reservesr13andr12,3reservesr13,r12andr11, and4reservesr13throughr10๐ธ. The default,0, doesn't reserve any registers at all.-msave-acc-in-interrupts: tells interrupt handler functions to preserve the accumulator register ๐ซถ. This only matters if normal code might be using the accumulator, like when it's doing 64-bit multiplications ๐ฅ. By default GCC ignores the accumulator, because that makes the interrupt handlers faster โญ.-mpid,-mno-pid: turns on generation of position independent data ๐. When it's enabled, any access to constant data happens as an offset from a base address held in a register. That means the location of constant data can be figured out at run time without the executable needing to be relocated, which is a huge win for embedded apps with tight memory constraints ๐. Data that can be modified isn't affected by this option.
Heads up, bestie: using this feature reserves a register, usually r13, for the constant data base address ๐. That can make code slower and/or larger, especially in complicated functions.
Which register actually holds the constant data base address depends on whether -msmall-data-limit and/or -mint-register are turned on. Starting at r13 and working downwards, registers get allocated first for -mint-register, then -mpid, and finally -msmall-data-limit. So the small data area register could end up being r8 if both -mint-register=4 and -mpid are on the command line ๐.
By default this feature is not enabled. The default can be restored with the -mno-pid command-line option ๐
.
-mno-warn-multiple-fast-interrupts,-mwarn-multiple-fast-interrupts: this pair is all about whether GCC yells at you when it finds more than one fast interrupt handler while compiling a file ๐ฃ. The-mno-version stops GCC from issuing that warning. The default is to warn for each extra fast interrupt handler it finds, since the RX only supports one such interrupt ๐จ.-mallow-string-insns,-mno-allow-string-insns: enables or disables the string manipulation instructionsSMOVF,SCMPU,SMOVB,SMOVU,SUNTILandSWHILE, plus theRMPAinstruction ๐งต. These may prefetch data, which is not safe to do if you're accessing an I/O register ๐ฌ (see section 12.2.7 of the RX62N Group User's Manual for more info).
They're allowed by default, but GCC can't reliably detect every situation where a string instruction might be used to access an I/O register, so they can't be turned off automatically ๐ซ . Instead it's on the programmer: if your program accesses I/O space, use -mno-allow-string-insns.
When these are enabled, GCC defines the C preprocessor symbol __RX_ALLOW_STRING_INSNS__. Otherwise it defines __RX_DISALLOW_STRING_INSNS__ ๐ง.
-mjsr,-mno-jsr: use only (or not only)JSRinstructions to access functions ๐. This is handy when your code size goes past the range ofBSRinstructions. Also,-mno-jsrdoesn't mean "don't useJSR". It just means any type of branch may be used ๐ .
Note: the generic GCC command-line option -ffixed-reg has special significance to the RX port when it's used with the interrupt function attribute ๐. That attribute marks a function meant to process fast interrupts. GCC makes sure it only uses r10, r11, r12 and/or r13, and only if the normal use of the corresponding registers has been restricted via -ffixed-reg or -mint-register ๐ซถ.
โจ S/390 and zSeries Options โจ
These are the -m options defined for the S/390 and zSeries architecture ๐ธ.
-mhard-float,-msoft-float: use (or don't use) hardware floating-point instructions and registers for floating-point operations ๐ฅ. With-msoft-float, functions inlibgcc.ado the floating-point work. With-mhard-float, the compiler generates IEEE floating-point instructions. This is the default ๐.-mhard-dfp,-mno-hard-dfp: use (or skip) the hardware decimal-floating-point instructions for decimal-floating-point operations ๐งฎ. With-mno-hard-dfp, functions inlibgcc.aare used to do the work. With-mhard-dfp, the compiler generates decimal-floating-point hardware instructions. This is the default for-march=z9-ecor higher โจ.-mlong-double-64,-mlong-double-128: these switches control the size of thelong doubletype ๐. A size of 64 bits makeslong doubleequivalent todouble, and that's the default ๐.-mbackchain,-mno-backchain: stores (or doesn't store) the address of the caller's frame as a backchain pointer in the callee's stack frame ๐ฆ. A backchain may be needed to allow debugging with tools that don't understand DWARF call frame information. When-mno-packed-stackis in effect, the backchain pointer is stored at the bottom of the stack frame. When-mpacked-stackis in effect, the backchain goes into the topmost word of the 96/160 byte register save area.
In general, code compiled with -mbackchain is call-compatible with code compiled with -mmo-backchain (yes, that's the typo in the original, bestie ๐). However, using the backchain for debugging purposes usually requires the whole binary to be built with -mbackchain.
Not supported: the combination of-mbackchain,-mpacked-stackand-mhard-float๐ซ. To build a Linux kernel, use-msoft-float.
The default is to not maintain the backchain.
-mpacked-stack,-mno-packed-stack: uses (or doesn't use) the packed stack layout ๐ฆ. With-mno-packed-stack, the compiler uses all the fields of the 96/160 byte register save area only for their default purpose, so unused fields still take up stack space ๐. With-mpacked-stack, register save slots are densely packed at the top of the register save area, and unused space gets reused for other purposes, which means more efficient use of the available stack space โจ. However, when-mbackchainis also in effect, the topmost word of the save area is always used to store the backchain, and the return address register is always saved two words below the backchain.
As long as the stack frame backchain isn't used, code generated with -mpacked-stack is call-compatible with code generated with -mno-packed-stack. Some non-FSF releases of GCC 2.95 for S/390 or zSeries generated code that uses the stack frame backchain at run time, not just for debugging purposes. That code is not call-compatible with code compiled with -mpacked-stack.
Also a no-go: the combination of-mbackchain,-mpacked-stackand-mhard-floatisn't supported ๐ซ. To build a Linux kernel, use-msoft-float.
The default is to not use the packed stack layout.
-msmall-exec,-mno-small-exec: generates (or doesn't generate) code using thebrasinstruction for subroutine calls ๐. This only works reliably if the total executable size doesn't exceed 64k. The default is to use thebasrinstruction instead, which doesn't have this limitation ๐ .-m64,-m31: when you pass-m31, the code is compliant with the GNU/Linux for S/390 ABI ๐งฉ. When you pass-m64, it's compliant with the GNU/Linux for zSeries ABI. This lets GCC generate 64-bit instructions ๐ข. For the s390 targets the default is-m31, while the s390x targets default to-m64.-mzarch,-mesa:-mzarchgenerates code using the instructions available on z/Architecture ๐.-mesagenerates code using the instructions available on ESA/390 ๐ฆ. Note that-mesais not possible with-m64๐ซ. When you're generating code compliant with the GNU/Linux for S/390 ABI, the default is-mesa. For the GNU/Linux for zSeries ABI, the default is-mzarch.-mhtm,-mno-htm:-mhtmenables a set of builtins that use instructions from the transactional execution facility, introduced with the IBM zEnterprise EC12 machine generation. Go peek at S/390 System z Built-in Functions for the deets ๐.-mhtmis enabled by default when using-march=zEC12๐.-mvx,-mno-vx:-mvxgenerates code using the instructions available with the vector extension facility, introduced with the IBM z13 machine generation โก. This option changes the ABI for some vector type values when it comes to alignment and calling conventions. If vector type values are being used in an ABI-relevant context, a GAS.gnu_attributecommand will be added to mark the resulting binary with the ABI used ๐ท๏ธ.-mvxis enabled by default when using-march=z13๐.-mzvector,-mno-zvectorโ okay bestie,-mzvectorswitches on vector language extensions and builtins ๐ using the instructions from the vector extension facility that came with the IBM z13 machine generation โจ. It letsvectorwork as a keyword for defining vector type variables and arguments ๐. Butvectoronly works when GNU extensions are enabled. It will NOT be expanded if you ask for strict standard compliance, like with-std=c99๐ญ. On top of the GCC low-level builtins,-mzvectoralso adds a set of builtins made for compatibility with AltiVec-style implementations like Power and Cell ๐ฆ. To actually use those, you need to include the header filevecintrin.h๐ซถ.-mzvectoris disabled by default ๐.-mmvcle,-mno-mvcleโ generates (or skips) code using themvcleinstruction for block moves ๐ง. With-mno-mvcle, GCC uses anmvcloop instead ๐. This is the default unless you're optimizing for size โจ.-mdebug,-mno-debugโ prints (or doesn't print) extra debug info while compiling ๐. The default is to not print debug info ๐.-march=cpu-typeโ generates code that runs oncpu-type, which is the name of a system representing a certain processor type ๐. The possible values arez900/arch5,z990/arch6,z9-109,z9-ec/arch7,z10/arch8,z196/arch9,zEC12,z13/arch11,z14/arch12,z15/arch13, andnative๐. The default is-march=z900๐ธ.
Using native as the cpu type picks the best architecture option for your host processor ๐ฅ. But -march=native has no effect if GCC doesn't recognize the processor ๐.
-mtune=cpu-typeโ tunes everything applicable about the generated code tocpu-type๐ฏ, except for the ABI and the set of available instructions ๐. The list ofcpu-typevalues is the same as for-marchโจ. The default is whatever value is used for-march๐.-mtpf-trace,-mno-tpf-traceโ adds (or doesn't add) TPF OS specific branches to trace routines in the operating system ๐ฆ. This is off by default, even when you're compiling for the TPF OS ๐ญ.-mtpf-trace-skip,-mno-tpf-trace-skipโ changes (or doesn't change) the default branch targets enabled by-mtpf-traceso they point to specialized trace routines ๐ง. These let you selectively skip function trace entries for the TPF OS โจ. It's off by default, even when you're compiling for the TPF OS and specifying-mtpf-trace๐ .-mfused-madd,-mno-fused-maddโ generates code that uses (or doesn't use) the floating-point multiply and accumulate instructions ๐ฅ. These get generated by default if hardware floating point is used ๐ซถ.-mwarn-framesize=framesizeโ emits a warning if the current function exceeds the given frame size โ ๏ธ. This is a compile-time check, so it doesn't have to be a real problem when the program runs ๐ธ. It's meant to spot functions that most probably cause a stack overflow ๐. It's super useful in environments with a limited stack size, like the Linux kernel ๐ง.-mwarn-dynamicstackโ emits a warning if the function callsallocaor uses dynamically-sized arrays ๐. This is generally a bad idea with a limited stack size ๐.-mstack-guard=stack-guard,-mstack-size=stack-sizeโ when these are provided, the S/390 back end adds extra instructions to the function prologue ๐ก๏ธ. These trigger a trap if the stack size isstack-guardbytes above thestack-size๐ค. (Remember, the stack on S/390 grows downward ๐ง .) If you leave outstack-guard, GCC picks the smallest power of 2 that's larger than the frame size of the compiled function ๐.
These options are meant to help you debug stack overflow problems ๐. The extra code causes only little overhead, so it can also be used in production-like systems without a big performance hit ๐. The values have to be exact powers of 2, and stack-size has to be greater than stack-guard without going over 64k ๐. To be efficient, the extra code assumes the stack starts at an address aligned to the value given by stack-size โจ. Also, stack-guard can only be used together with stack-size ๐ซถ.
-mhotpatch=pre-halfwords,post-halfwordsโ if hotpatch is enabled, a "hot-patching" function prologue is generated for all functions in the compilation unit ๐ฅ. The function label gets prepended with the given number of two-byte NOP instructions (pre-halfwords, maximum 1000000) ๐ง. After the label,2 * post-halfwordsbytes get appended, using the largest NOP-like instructions the architecture allows (maximum 1000000) โจ.
If both arguments are zero, hotpatching is disabled ๐ โโ๏ธ.
You can override this option for individual functions with the hotpatch attribute ๐
.
โจ Score Options โจ
These options are defined for Score implementations ๐:
-mebโ compiles code for big-endian mode ๐. This is the default ๐.-melโ compiles code for little-endian mode ๐ฆ.-mnhwloopโ disables generation ofbcnzinstructions ๐ โโ๏ธ.-mulsโ enables generation of unaligned load and store instructions ๐ซถ.-mmacโ enables the use of multiply-accumulate instructions ๐ฅ. It's disabled by default ๐.-mscore5โ specifies SCORE5 as the target architecture ๐.-mscore5uโ specifies SCORE5U as the target architecture ๐ธ.-mscore7โ specifies SCORE7 as the target architecture ๐ . This is the default โจ.-mscore7dโ specifies SCORE7D as the target architecture ๐ง.
๐ธ SH Options ๐ธ
These -m options are defined for the SH implementations ๐:
-m1โ generates code for the SH1 ๐.-m2โ generates code for the SH2 ๐.-m2eโ generates code for the SH2e ๐.-m2a-nofpuโ generates code for the SH2a without an FPU ๐ค. Or, for a SH2a-FPU, it does this in such a way that the floating-point unit isn't used ๐.-m2a-single-onlyโ generates code for the SH2a-FPU in such a way that no double-precision floating-point operations are used ๐ฆ.-m2a-singleโ generates code for the SH2a-FPU, assuming the floating-point unit is in single-precision mode by default โจ.-m2aโ generates code for the SH2a-FPU, assuming the floating-point unit is in double-precision mode by default ๐.-m3โ generates code for the SH3 ๐.-m3eโ generates code for the SH3e ๐.-m4-nofpuโ generates code for the SH4 without a floating-point unit ๐ โโ๏ธ.-m4-single-onlyโ generates code for the SH4 with a floating-point unit that only supports single-precision arithmetic ๐ซถ.-m4-singleโ generates code for the SH4, assuming the floating-point unit is in single-precision mode by default ๐ฅ.-m4โ generates code for the SH4 ๐.-m4-100โ generates code for SH4-100 โจ.-m4-100-nofpuโ generates code for SH4-100 in such a way that the floating-point unit isn't used ๐ .-m4-100-singleโ generates code for SH4-100, assuming the floating-point unit is in single-precision mode by default ๐.-m4-100-single-onlyโ generates code for SH4-100 in such a way that no double-precision floating-point operations are used ๐ฆ.-m4-200โ generates code for SH4-200 โจ.-m4-200-nofpuโ generates code for SH4-200 without, in such a way that the floating-point unit isn't used ๐ญ.-m4-200-singleโ generates code for SH4-200, assuming the floating-point unit is in single-precision mode by default ๐ธ.-m4-200-single-onlyโ generates code for SH4-200 in such a way that no double-precision floating-point operations are used ๐.-m4-300โ generates code for SH4-300 โจ.-m4-300-nofpuโ generates code for SH4-300 without, in such a way that the floating-point unit isn't used ๐.-m4-300-singleโ generates code for SH4-300 in such a way that no double-precision floating-point operations are used ๐ฆ.-m4-300-single-onlyโ generates code for SH4-300 in such a way that no double-precision floating-point operations are used ๐ฆ.-m4-340โ generates code for SH4-340 (no MMU, no FPU) ๐ง.-m4-500โ generates code for SH4-500 (no FPU) ๐. It passes-isa=sh4-nofputo the assembler ๐ซถ.-m4a-nofpuโ generates code for the SH4al-dsp, or for a SH4a in such a way that the floating-point unit isn't used ๐ .-m4a-single-onlyโ generates code for the SH4a in such a way that no double-precision floating-point operations are used ๐ฆ.-m4a-singleโ generates code for the SH4a, assuming the floating-point unit is in single-precision mode by default โจ.-m4aโ generates code for the SH4a ๐.-m4alโ same as-m4a-nofpu, except it implicitly passes-dspto the assembler ๐. GCC doesn't generate any DSP instructions at the moment ๐ญ.-mbโ compiles code for the processor in big-endian mode ๐.-mlโ compiles code for the processor in little-endian mode ๐.-mdalignโ aligns doubles at 64-bit boundaries ๐. Heads up: this changes the calling conventions, so some functions from the standard C library won't work unless you recompile them first with-mdalignโ ๏ธ.-mrelaxโ shortens some address references at link time, when possible ๐. It does this using the linker option-relaxโจ.-mbigtableโ uses 32-bit offsets inswitchtables ๐ธ. The default is 16-bit offsets ๐ โโ๏ธ.-mbitopsโ enables the use of bit manipulation instructions on SH2A ๐ฅ.-mfmovdโ enables the use of thefmovdinstruction ๐ฆ. Check-mdalignfor alignment constraints ๐.-mrenesasโ complies with the calling conventions defined by Renesas ๐.-mno-renesasโ complies with the calling conventions defined for GCC before the Renesas conventions were available ๐ง. This option is the default for all targets of the SH toolchain ๐ .-mnomacsaveโ marks theMACregister as call-clobbered, even if-mrenesasis given ๐.-mieee,-mno-ieeeโ controls the IEEE compliance of floating-point comparisons ๐งฎ. This affects how cases where the result of a comparison is unordered get handled ๐ค. By default,-mieeeis implicitly enabled ๐. If-ffinite-math-onlyis enabled,-mno-ieeeis implicitly set, which makes floating-point greater-equal and less-equal comparisons faster ๐. You can override these implicit settings by specifying either-mieeeor-mno-ieee๐ซถ.-minline-ic_invalidateโ okay so this one tells the compiler to inline code that invalidates instruction cache entries right after it sets up nested function trampolines ๐ . It does nothing if-musermodeis active and your chosen code generation option (like-m4) doesn't allow theicbiinstruction. If your code gen option doesn't allowicbiand-musermodeisn't on, the inlined code pokes the instruction cache address array directly with an associative write ๐ฌ. That needs privileged mode at run time, and it fails if the cache line was mapped through the TLB and has since become unmapped ๐.-misizeโ dumps instruction size and location into the assembly output ๐ง-mpadstructโ โ ๏ธ deprecated, so please don't reach for it ๐. It pads structures out to a multiple of 4 bytes, which is incompatible with the SH ABI ๐-matomic-model=modelโ sets the model for atomic operations, plus any extra parameters, as a comma separated list ๐ฅ. For the full scoop on the atomic built-in functions, check out __atomic Builtins โจ. These are the models and parameters you can pick from:noneโ turns off compiler generated atomic sequences and emits library calls for atomic operations instead. This is the default when the target isn'tsh*-*-linux*๐ธsoft-gusaโ generates GNU/Linux compatible gUSA software atomic sequences for the atomic built-ins ๐ฆ. These need extra help from the system's interrupt/exception handling code and only work on SH3* and SH4* single-core systems. It's turned on by default when the target issh*-*-linux*and the chip is SH3* or SH4*. On SH4A, it also partly uses the hardwaremovli.landmovco.linstructions for faster code, unless you specifystrict๐ฅsoft-tcbโ generates software atomic sequences that use a variable in the thread control block ๐. It's a spin on the gUSA sequences that also works on SH1* and SH2* targets. Like gUSA, it needs help from the interrupt/exception handling code and is only suitable for single-core systems. When you use this model, you have to specify thegbr-offset=parameter too โ ๏ธsoft-imaskโ generates software atomic sequences that temporarily turn off interrupts by settingSR.IMASK = 1111๐. This only works when the program runs in privileged mode and is only suitable for single-core systems. It doesn't need any extra help from the interrupt/exception handling code. It's enabled by default when the target issh*-*-linux*and the chip is SH1* or SH2* โจhard-llcsโ generates hardware atomic sequences using onlymovli.landmovco.l๐. It's only available on SH4A and is great for multi-core systems. The hardware only handles 32 bit atomic variables, so 8 and 16 bit variables get emulated with 32 bit accesses. Code built with this is also compatible with other software atomic model interrupt/exception handling systems when it runs on an SH4A system. This model doesn't need any extra support from the interrupt/exception handling code ๐ซถgbr-offset=โ the offset, in bytes, of the variable inside the thread control block structure that the generated atomic sequences should use whensoft-tcbis selected ๐. Other models just ignore it. The value has to be an integer multiple of four and fall in the range 0-1020 ๐strictโ stops you from mixing multiple atomic models, even ones that are compatible with each other ๐ . It makes the compiler generate sequences for only the model you specified ๐
-mtasโ generates thetas.bopcode for__atomic_test_and_set๐ซง. Heads up, though: depending on your hardware and software setup, this can drag down overall performance because of the operand cache line flushes thattas.bimplies ๐ญ. On multi-core SH4A processors,tas.bhas to be used with caution, since it can cause data corruption with certain cache configurations โ ๏ธ-mprefergotโ when you're making position-independent code, function calls get emitted through the Global Offset Table instead of the Procedure Linkage Table ๐ง-musermode,-mno-usermodeโ-musermodestops the compiler from generating privileged mode code, and-mno-usermodelets it generate that code ๐. Using-musermodealso implies-mno-inline-ic_invalidateif the inlined code wouldn't work in user mode ๐.-musermodeis the default when the target issh*-*-linux*. If the target is SH1* or SH2*,-musermodedoes nothing, since those chips don't have a user mode ๐-multcost=numberโ sets the cost the compiler assumes for a multiply instruction ๐ข-mdiv=strategyโ picks the division strategy for integer division operations ๐งฎ. Thestrategycan be one of:call-div1โ calls a library function that uses the single-step division instructiondiv1to do the math. Dividing by zero gives an unspecified result and doesn't trap ๐ธ. This is the default, except for SH4, SH2A and SHcompactcall-fpโ calls a library function that does the operation in double precision floating point ๐. Dividing by zero causes a floating-point exception ๐ฅ. This is the default for SHcompact with an FPU. If you pick this on a target without a double precision FPU, it falls back tocall-div1๐ซcall-tableโ calls a library function that uses a lookup table for small divisors, plus thediv1instruction with case distinction for bigger divisors ๐ง . Dividing by zero gives an unspecified result and doesn't trap. This is the default for SH4. If you pick this on a target without dynamic shift instructions, it falls back tocall-div1๐
When you don't specify a strategy, the default is picked based on the current target. On SH2A, the default is to use the divs and divu instructions instead of library function calls โจ
-maccumulate-outgoing-argsโ reserves space for outgoing arguments once, in the function prologue, instead of around each call ๐ฆ. This is generally good for performance and size. It's also needed for unwinding, so the stack frame doesn't get changed around conditional code ๐ฆ-mdivsi3_libfunc=nameโ sets the name of the library function used for 32-bit signed division toname๐ท๏ธ. This only changes the name used in the call division strategies. The compiler still expects the same sets of input, output and clobbered registers as if you hadn't used this option ๐-mfixed-range=register-rangeโ makes the compiler treat the given register range as fixed registers ๐. A fixed register is one the register allocator isn't allowed to use. This comes in handy when you're compiling kernel code ๐ซถ. A register range is written as two registers separated by a dash, and you can list multiple ranges separated by a comma ๐-mbranch-cost=numโ tells the compiler to assumenumis the cost of a branch instruction ๐ฟ. Higher numbers make the compiler try harder to generate branch-free code when it can. If you don't specify it, the value is picked based on the processor type you're compiling for ๐-mzdcbranch,-mno-zdcbranchโ-mzdcbranchassumes that zero displacement conditional branch instructionsbtandbfare fast, so the compiler prefers zero displacement branch code sequences โก.-mno-zdcbranchsays the opposite ๐ . It's enabled by default for SH4 and SH4A, and you can turn it off explicitly with-mno-zdcbranch๐ธ-mcbranch-force-delay-slotโ forces the use of delay slots for conditional branches ๐ฆฅ. If no suitable instruction turns up, it fills the delay slot with anop๐ค. This option is disabled by default. Turn it on to work around the hardware bugs found in the original SH7055 ๐ง-mfused-madd,-mno-fused-maddโ-mfused-maddgenerates code that uses the floating-point multiply and accumulate instructions, and-mno-fused-maddgenerates code that doesn't ๐งช. These instructions are generated by default if hardware floating point is in use. The machine-dependent-mfused-maddoption is now mapped to the machine-independent-ffp-contract=fastoption, and-mno-fused-maddis mapped to-ffp-contract=off๐-mfsca,-mno-fscaโ lets you allow or disallow the compiler from emitting thefscainstruction for sine and cosine approximations ๐. The-mfscaoption has to be paired with-funsafe-math-optimizations. It's enabled by default when generating code for SH4A. Using-mno-fscadisables sine and cosine approximations, even if-funsafe-math-optimizationsis in effect ๐ซ-mfsrra,-mno-fsrraโ same idea, but for thefsrrainstruction and reciprocal square root approximations ๐. The-mfsrraoption has to be paired with both-funsafe-math-optimizationsand-ffinite-math-only. It's enabled by default when generating code for SH4A. Using-mno-fsrradisables reciprocal square root approximations, even if-funsafe-math-optimizationsand-ffinite-math-onlyare in effect ๐-mpretend-cmoveโ prefers zero-displacement conditional branches for conditional move instruction patterns ๐. This can give you faster code on the SH4 processor ๐จ-mfdpicโ generates code using the FDPIC ABI ๐
โจ Solaris 2 Options โจ
These -m options are supported on Solaris 2 ๐
-mclear-hwcapโ tells the compiler to remove the hardware capabilities generated by the Solaris assembler ๐งน. You only need this when object files use ISA extensions the current machine doesn't support, but the code checks at runtime whether or not to use them ๐ซถ-mimpure-textโ used alongside-shared, this tells the compiler not to pass-z textto the linker when linking a shared object ๐ฆ. With this option, you can link position-dependent code into a shared object ๐
okay so -mimpure-text is giving "I know what I'm doing" energy ๐
It shuts up the linker complaint about "relocations remain against allocatable but non-writable sections" ๐ BUT ngl this is a trap, bestie. The relocations trigger copy-on-write, so the shared object is not actually shared across processes anymore ๐ญ The real move is to compile all your source code with -fpic or -fPIC instead ๐ซถ
These switches are also supported on Solaris 2, so you get these extras too:
-pthreadsโ literally just a synonym for-pthread๐งต
โจ SPARC Options โจ
These -m options are supported on the SPARC ๐ธ
-mno-app-regs,-mapp-regsโ-mapp-regsmakes the output use global registers 2 through 4, which the SPARC SVR4 ABI reserves for applications ๐ Like global register 1, each of global registers 2 through 4 then gets treated as an allocable register that function calls clobber. This one is the default. If you want to be fully SVR4 ABI-compliant (with a bit of a performance hit), go with-mno-app-regs. You should compile libraries and system software with this option ๐-mflat,-mno-flatโ With-mflat, the compiler skips the save/restore instructions and uses a "flat" or single register window model ๐ฆ This is compatible with the regular register window model. The local registers and the input registers (0--5) are still treated as "call-saved" registers, so they get saved on the stack as needed. With-mno-flat(the default), the compiler generates save/restore instructions, except for leaf functions. This is the normal operating mode โจ-mfpu,-mhard-floatโ Generates output with floating-point instructions. This is the default ๐ฅ-mno-fpu,-msoft-floatโ Generates output that uses library calls for floating point instead ๐
โ ๏ธ Warning: the requisite libraries are not available for all SPARC targets ๐ญ Normally the facilities of the machine's usual C compiler get used, but that can't be done directly in cross-compilation. You have to make your own arrangements to provide suitable library functions for cross-compilation. The embedded targetssparc-*-aoutandsparclite-*-*do provide software floating-point support.
-msoft-float changes the calling convention in the output file, so it's only useful if you compile all of a program with this option ๐ซถ In particular, you need to compile libgcc.a, the library that comes with GCC, with -msoft-float for this to work.
-mhard-quad-floatโ Generates output with quad-word (long double) floating-point instructions ๐-msoft-quad-floatโ Generates output that uses library calls for quad-word (long double) floating-point instructions. The functions called are the ones specified in the SPARC ABI. This is the default ๐ As of this writing, there are no SPARC implementations with hardware support for the quad-word floating-point instructions. They all invoke a trap handler for one of these instructions, and then the trap handler emulates the effect. Because of that trap handler overhead, this is much slower than calling the ABI library routines, so-msoft-quad-floatis the default ๐-mno-unaligned-doubles,-munaligned-doublesโ-mno-unaligned-doublesassumes that doubles have 8-byte alignment, and this is the default ๐ With-munaligned-doubles, GCC only assumes 8-byte alignment for doubles if they're contained in another type or if they have an absolute address. Otherwise, it assumes 4-byte alignment. Using this option avoids some rare compatibility problems with code generated by other compilers. It isn't the default because it results in a performance loss, especially for floating-point code ๐-muser-mode,-mno-user-modeโ Does not generate code that can only run in supervisor mode ๐ง This is only relevant to thecasainstruction emitted for the LEON3 processor. This is the default.-mfaster-structs,-mno-faster-structsโ With-mfaster-structs, the compiler assumes structures should have 8-byte alignment ๐ This enables pairs oflddandstdinstructions for copies in structure assignment, in place of twice as manyldandstpairs. However, this changed alignment directly violates the SPARC ABI. So it's only meant for targets where the developer acknowledges that their resulting code isn't directly in line with the ABI rules ๐-mstd-struct-return,-mno-std-struct-returnโ With-mstd-struct-return, the compiler generates checking code in functions returning structures or unions. This detects size mismatches between the two sides of function calls, as per the 32-bit ABI ๐ The default is-mno-std-struct-return. This option has no effect in 64-bit mode.-mlra,-mno-lraโ Enables Local Register Allocation ๐ธ This has been the default for SPARC since GCC 7, so you need to pass-mno-lraif you want the old Reload.-mcpu=cpu_typeโ Sets the instruction set, register set, and instruction scheduling parameters for machine typecpu_type๐ Supported values forcpu_typearev7,cypress,v8,supersparc,hypersparc,leon,leon3,leon3v7,leon5,sparclite,f930,f934,sparclite86x,sparclet,tsc701,v9,ultrasparc,ultrasparc3,niagara,niagara2,niagara3,niagara4,niagara7andm8.
Native Solaris and GNU/Linux toolchains also accept the value native, which picks the best architecture option for the host processor ๐ง -mcpu=native has no effect if GCC doesn't recognize the processor.
Default instruction scheduling parameters get used for values that select an architecture and not a specific implementation. Those are v7, v8, sparclite, sparclet, and v9.
Here's the lineup of each supported architecture and its implementations:
v7โcypress,leon3v7v8โsupersparc,hypersparc,leon,leon3,leon5sparcliteโf930,f934,sparclite86xsparcletโtsc701v9โultrasparc,ultrasparc3,niagara,niagara2,niagara3,niagara4,niagara7,m8
By default (unless configured otherwise), GCC generates code for the V7 variant of the SPARC architecture ๐ฆ With -mcpu=cypress, the compiler additionally optimizes for the Cypress CY7C602 chip, as used in the SPARCStation/SPARCServer 3xx series. This is also appropriate for the older SPARCStation 1, 2, IPX etc.
With -mcpu=v8, GCC generates code for the V8 variant. The only difference from V7 code is that the compiler emits the integer multiply and integer divide instructions that exist in SPARC-V8 but not in SPARC-V7 โจ With -mcpu=supersparc, the compiler additionally optimizes for the SuperSPARC chip, as used in the SPARCStation 10, 1000 and 2000 series.
With -mcpu=sparclite, GCC generates code for the SPARClite variant. This adds the integer multiply, integer divide step, and scan ("ffs") instructions that exist in SPARClite but not in SPARC-V7 ๐ With -mcpu=f930, the compiler additionally optimizes for the Fujitsu MB86930 chip, which is the original SPARClite, with no FPU. With -mcpu=f934, it optimizes for the Fujitsu MB86934 chip, the more recent SPARClite with FPU.
With -mcpu=sparclet, GCC generates code for the SPARClet variant. This adds the integer multiply, multiply/accumulate, integer divide step, and scan ("ffs") instructions that exist in SPARClet but not in SPARC-V7 ๐ง With -mcpu=tsc701, the compiler additionally optimizes for the TEMIC SPARClet chip.
With -mcpu=v9, GCC generates code for the V9 variant. This adds 64-bit integer and floating-point move instructions, 3 additional floating-point condition code registers, and conditional move instructions ๐ With -mcpu=ultrasparc, the compiler additionally optimizes for the Sun UltraSPARC I/II/IIi chips. With -mcpu=ultrasparc3, it optimizes for the Sun UltraSPARC III/III+/IIIi/IIIi+/IV/IV+ chips. With -mcpu=niagara, it optimizes for Sun UltraSPARC T1 chips. With -mcpu=niagara2, it optimizes for Sun UltraSPARC T2 chips. With -mcpu=niagara3, it optimizes for Sun UltraSPARC T3 chips. With -mcpu=niagara4, it optimizes for Sun UltraSPARC T4 chips. With -mcpu=niagara7, it optimizes for Oracle SPARC M7 chips. With -mcpu=m8, it optimizes for Oracle M8 chips ๐
-mtune=cpu_typeโ Sets the instruction scheduling parameters for machine typecpu_type, but doesn't touch the instruction set or register set the way-mcpu=cpu_typedoes ๐
The same values for -mcpu=cpu_type work for -mtune=cpu_type, but the only useful ones are the values that select a particular CPU implementation. Those are cypress, supersparc, hypersparc, leon, leon3, leon3v7, leon5, f930, f934, sparclite86x, tsc701, ultrasparc, ultrasparc3, niagara, niagara2, niagara3, niagara4, niagara7 and m8. With native Solaris and GNU/Linux toolchains, native can also be used ๐ง
-mv8plus,-mno-v8plusโ With-mv8plus, GCC generates code for the SPARC-V8+ ABI ๐ธ The difference from the V8 ABI is that the global and out registers are considered 64 bits wide. This is enabled by default on Solaris in 32-bit mode for all SPARC-V9 processors.-mvis,-mno-visโ With-mvis, GCC generates code that takes advantage of the UltraSPARC Visual Instruction Set extensions ๐ฆ The default is-mno-vis.-mvis2,-mno-vis2โ With-mvis2, GCC generates code that takes advantage of version 2.0 of the UltraSPARC Visual Instruction Set extensions ๐ฅ The default is-mvis2when targeting a CPU that supports such instructions, such as UltraSPARC-III and later. Setting-mvis2also sets-mvis.-mvis3,-mno-vis3โ With-mvis3, GCC generates code that takes advantage of version 3.0 of the UltraSPARC Visual Instruction Set extensions โญ The default is-mvis3when targeting a CPU that supports such instructions, such as niagara-3 and later. Setting-mvis3also sets-mvis2and-mvis.
-mvis4, -mno-vis4 โ okay so -mvis4 makes GCC write code that uses version 4.0 of the UltraSPARC Visual Instruction Set extensions ๐
. The default is -mvis4 when you're targeting a cpu that supports these, like niagara-7 and later. Setting -mvis4 also turns on -mvis3, -mvis2 and -mvis โจ
-mvis4b,-mno-vis4bโ With-mvis4b, GCC uses version 4.0 of the UltraSPARC Visual Instruction Set extensions, plus the extra VIS instructions introduced in the Oracle SPARC Architecture 2017 ๐ฅ. The default is-mvis4bwhen targeting a cpu that supports these, likem8and later. Setting-mvis4balso sets-mvis4,-mvis3,-mvis2and-mvis๐-mcbcond,-mno-cbcondโ With-mcbcond, GCC takes advantage of the UltraSPARC Compare-and-Branch-on-Condition instructions ๐ฆ. The default is-mcbcondwhen targeting a CPU that supports these, likeNiagara-4and later.-mfmaf,-mno-fmafโ With-mfmaf, GCC takes advantage of the UltraSPARC Fused Multiply-Add Floating-point instructions ๐ธ. The default is-mfmafwhen targeting a CPU that supports these, likeNiagara-3and later.-mfsmuld,-mno-fsmuldโ With-mfsmuld, GCC uses the Floating-point Multiply Single to Double (FsMULd) instruction ๐ง. The default is-mfsmuldwhen targeting a CPU that supports the architecture versions V8 or V9 with FPU, except-mcpu=leon.-mpopc,-mno-popcโ With-mpopc, GCC takes advantage of the UltraSPARC Population Count instruction ๐. The default is-mpopcwhen targeting a CPU that supports it, likeNiagara-2and later.-msubxc,-mno-subxcโ With-msubxc, GCC takes advantage of the UltraSPARC Subtract-Extended-with-Carry instruction โญ. The default is-msubxcwhen targeting a CPU that supports it, likeNiagara-7and later.-mfix-at697fโ Turns on the documented workaround for the single erratum of the Atmel AT697F processor, which is erratum #13 of the AT697E processor ๐ ๏ธ.-mfix-ut699โ Turns on the documented workarounds for the floating-point errata and the data cache nullify errata of the UT699 processor ๐ซถ.-mfix-ut700โ Turns on the documented workaround for the back-to-back store errata of the UT699E/UT700 processor ๐ .-mfix-gr712rcโ Turns on the documented workaround for the back-to-back store errata of the GR712RC processor ๐.
These -m options are supported in addition to the above on SPARC-V9 processors in 64-bit environments, and they're lowkey essential if that's your setup โจ
-m32,-m64โ Generates code for a 32-bit or 64-bit environment ๐. The 32-bit environment setsint,longand pointer to 32 bits. The 64-bit environment setsintto 32 bits andlongand pointer to 64 bits.-mcmodel=whichโ Sets the code model to one of these, and yes, it's giving main character energy ๐:medlowโ The Medium/Low code model: 64-bit addresses, and programs must be linked in the low 32 bits of memory. Programs can be statically or dynamically linked.medmidโ The Medium/Middle code model: 64-bit addresses, and programs must be linked in the low 44 bits of memory. The text and data segments must be less than 2GB in size, and the data segment must be located within 2GB of the text segment.medanyโ The Medium/Anywhere code model: 64-bit addresses, and programs may be linked anywhere in memory. The text and data segments must be less than 2GB in size, and the data segment must be located within 2GB of the text segment.embmedanyโ The Medium/Anywhere code model for embedded systems: 64-bit addresses. The text and data segments must be less than 2GB in size, both starting anywhere in memory (determined at link time). The global register%g4points to the base of the data segment. Programs are statically linked, and PIC is not supported.
-mmemory-model=mem-modelโ Sets the memory model in force on the processor to one of these ๐ง :defaultโ The default memory model for the processor and operating system.rmoโ Relaxed Memory Orderpsoโ Partial Store Ordertsoโ Total Store Orderscโ Sequential Consistency
These memory models are formally defined in Appendix D of the SPARC-V9 architecture manual, as set in the processor's "PSTATE.MM" field ๐.
-mstack-bias,-mno-stack-biasโ With-mstack-bias, GCC assumes that the stack pointer, and the frame pointer if there is one, are offset by-2047, which must be added back when making stack frame references. This is the default in 64-bit mode. Otherwise, GCC assumes no such offset is present ๐.
โจ Options for System V โจ
These additional options are available on System V Release 4 for compatibility with other compilers on those systems ๐.
-Gโ Creates a shared object. It is recommended that-symbolicor-sharedbe used instead.-Qyโ Identifies the versions of each tool used by the compiler, in a.identassembler directive in the output ๐.-Qnโ Refrains from adding.identdirectives to the output file. This is the default.-YP,dirsโ Searches the directoriesdirs, and no others, for libraries specified with-l๐.-Ym,dirโ Looks in the directorydirto find the M4 preprocessor. The assembler uses this option ๐ง.
๐ TILE-Gx Options ๐
These -m options are supported on the TILE-Gx ๐
:
-mcmodel=smallโ Generates code for the small model. The distance for direct calls is limited to 500M in either direction. PC-relative addresses are 32 bits. Absolute addresses support the full address range.-mcmodel=largeโ Generates code for the large model. There is no limitation on call distance, pc-relative addresses, or absolute addresses ๐ฆ.-mcpu=nameโ Selects the type of CPU to be targeted. Currently the only supported type istilegx.-m32,-m64โ Generates code for a 32-bit or 64-bit environment. The 32-bit environment setsint,long, and pointer to 32 bits. The 64-bit environment setsintto 32 bits andlongand pointer to 64 bits.-mbig-endian,-mlittle-endianโ Generates code in big or little endian mode, respectively ๐ซถ.
๐ TILEPro Options ๐
These -m options are supported on the TILEPro ๐ธ:
-mcpu=nameโ Selects the type of CPU to be targeted. Currently the only supported type istilepro.-m32โ Generates code for a 32-bit environment, which setsint,long, and pointer to 32 bits. This is the only supported behavior, so the flag is essentially ignored ๐.
๐ V850 Options ๐
These -m options are defined for V850 implementations ๐:
-mlong-calls,-mno-long-callsโ Treats all calls as being far away (or near). If calls are assumed to be far away, the compiler always loads the function's address into a register, and calls indirect through the pointer ๐.-mno-ep,-mepโ Does not optimize (or does optimize) basic blocks that use the same index pointer 4 or more times to copy the pointer into the "ep" register, and use the shorter "sld" and "sst" instructions. The-mepoption is on by default if you optimize โจ.-mno-prolog-function,-mprolog-functionโ Does not use (or does use) external functions to save and restore registers at the prologue and epilogue of a function. The external functions are slower, but use less code space if more than one function saves the same number of registers. The-mprolog-functionoption is on by default if you optimize ๐ง .-mspaceโ Tries to make the code as small as possible. At present, this just turns on the-mepand-mprolog-functionoptions ๐.-mtda=nโ Puts static or global variables whose size isnbytes or less into the tiny data area that register "ep" points to. The tiny data area can hold up to 256 bytes in total (128 bytes for byte references) ๐ฅฐ.-msda=nโ Puts static or global variables whose size isnbytes or less into the small data area that register "gp" points to. The small data area can hold up to 64 kilobytes ๐.-mzda=nโ Puts static or global variables whose size isnbytes or less into the first 32 kilobytes of memory ๐ธ.-mv850โ Specifies that the target processor is the V850 ๐ฆ.-mv850e3v5โ Specifies that the target processor is the V850E3V5. The preprocessor constant "__v850e3v5__" is defined if this option is used ๐ฅ.-mv850e2v4โ Specifies that the target processor is the V850E3V5. This is an alias for the-mv850e3v5option ๐ซถ.-mv850e2v3โ Specifies that the target processor is the V850E2V3. The preprocessor constant "__v850e2v3__" is defined if this option is used ๐.-mv850e2โ Specifies that the target processor is the V850E2. The preprocessor constant "__v850e2__" is defined if this option is used ๐ .-mv850e1โ Specifies that the target processor is the V850E1. The preprocessor constants "__v850e1__" and "__v850e__" are defined if this option is used ๐.-mv850esโ Specifies that the target processor is the V850ES. This is an alias for the-mv850e1option ๐.-mv850eโ Specifies that the target processor is the V850E. The preprocessor constant "__v850e__" is defined if this option is used ๐.
If neither -mv850 nor -mv850e nor -mv850e1 nor -mv850e2 nor -mv850e2v3 nor -mv850e3v5 are defined, then a default target processor is chosen and the relevant __v850*__ preprocessor constant is defined ๐คทโโ๏ธ.
The preprocessor constants "__v850" and "__v851__" are always defined, regardless of which processor variant is the target ๐ง.
-mdisable-callt,-mno-disable-calltโ This option suppresses generation of the "CALLT" instruction for the v850e, v850e1, v850e2, v850e2v3 and v850e3v5 flavors of the v850 architecture ๐ซ.
This option is enabled by default when the RH850 ABI is in use (see -mrh850-abi), and disabled by default when the GCC ABI is in use. If "CALLT" instructions are being generated, then the C preprocessor symbol "__V850_CALLT__" is defined ๐.
-mrelax,-mno-relaxโ Passes on (or does not pass on) the-mrelaxcommand-line option to the assembler ๐ฆ.-mlong-jumps,-mno-long-jumpsโ Disables (or re-enables) the generation of PC-relative jump instructions ๐.-msoft-float,-mhard-floatโ okay so these two let you switch the generation of hardware floating point instructions off (or back on) ๐ฅ. This only matters when the target architecture isV850E2V3or higher. If hardware floating point instructions are being generated, the C preprocessor symbol__FPU_OK__gets defined, and if they aren't,__NO_FPU__gets defined instead ๐.-mloopโ enables the e3v5LOOPinstruction ๐. Heads up bestie: this one is NOT on by default when you pick the e3v5 architecture, because its use is still experimental ๐งช.-mrh850-abi,-mghsโ turns on support for the RH850 version of the V850 ABI ๐. This is the default, and with it the following rules apply:- Integer sized structures and unions get returned via a memory pointer instead of a register.
- Large structures and unions (more than 8 bytes in size) are passed by value.
- Functions are aligned to 16-bit boundaries.
- The
-m8byte-aligncommand-line option is supported. - The
-mdisable-calltcommand-line option is enabled by default. The-mno-disable-calltcommand-line option is not supported.
When this version of the ABI is enabled, the C preprocessor symbol __V850_RH850_ABI__ gets defined โจ.
-mgcc-abiโ the old-school GCC version of the V850 ABI ๐ฆ. With this one, the rules are:- Integer sized structures and unions come back in register
r10. - Large structures and unions (more than 8 bytes in size) are passed by reference.
- Functions are aligned to 32-bit boundaries, unless you're optimizing for size.
- The
-m8byte-aligncommand-line option is not supported. - The
-mdisable-calltcommand-line option is supported but not enabled by default.
- Integer sized structures and unions come back in register
When this version of the ABI is enabled, the C preprocessor symbol __V850_GCC_ABI__ gets defined ๐ธ.
-m8byte-align,-mno-8byte-alignโ letsdoubleandlong longtypes get aligned on 8-byte boundaries ๐. The default is to keep the alignment of all objects at 4 bytes max. When-m8byte-alignis in effect, the C preprocessor symbol__V850_8BYTE_ALIGN__gets defined.-mbig-switchโ generates code that's suitable for big switch tables ๐ง. Only reach for this one if the assembler or linker starts complaining about out of range branches within a switch table ๐.-mapp-regsโ makes the generated code user2andr5๐ . This is the default setting.-mno-app-regsโ makesr2andr5get treated as fixed registers.
๐ VAX Options ๐
These -m options are defined for the VAX ๐ท:
-munixโ skips outputting certain jump instructions (aobleqand so on) that the Unix assembler for the VAX can't handle across long ranges ๐ โโ๏ธ.-mgnuโ nope, the opposite! This one DOES output those jump instructions, on the assumption that the GNU assembler is being used ๐ซถ.-mgโ outputs code for G-format floating-point numbers instead of D-format ๐ข.
๐ฆ Visium Options ๐ฆ
-mdebugโ if your program does file I/O and is destined to run on an MCM target, link it with this one ๐. It causes the librarieslibc.aandlibdebug.ato get linked. You run the program on the target under the control of the GDB remote debugging stub ๐ ๏ธ.-msimโ same vibe, but for the simulator ๐งช. If your program does file I/O and is going to run on the simulator, link it with option (the manual forgot a word here, bestie ๐). This causes the librarieslibc.aandlibsim.ato get linked.-mfpu,-mhard-floatโ generates code containing floating-point instructions โก. This is the default.-mno-fpu,-msoft-floatโ generates code containing library calls for floating-point ๐.
Warning, this one is a whole vibe:-msoft-floatchanges the calling convention in the output file ๐ญ. That means it's only useful if you compile ALL of a program with this option. In particular, you need to compilelibgcc.a, the library that comes with GCC, with-msoft-floatfor this to work.
-mcpu=cpu_typeโ sets the instruction set, register set, and instruction scheduling parameters for the machine typecpu_type๐ง . The supported values forcpu_typearemcm,gr5andgr6.mcmis a synonym ofgr5, kept around for backward compatibility ๐ฐ๏ธ.- By default (unless configured otherwise), GCC generates code for the GR5 variant of the Visium architecture ๐.
- With
-mcpu=gr6, GCC generates code for the GR6 variant of the Visium architecture. The only difference from GR5 code is that the compiler will generate block move instructions ๐.
-mtune=cpu_typeโ sets the instruction scheduling parameters for the machine typecpu_type, but doesn't touch the instruction set or register set that-mcpu=cpu_typewould ๐ฏ.-msv-modeโ generates code for supervisor mode, where there are no restrictions on access to general registers ๐. This is the default.-muser-modeโ generates code for user mode, where access to some general registers is forbidden ๐ซ. On the GR5, registersr24tor31can't be accessed in this mode. On the GR6, only registersr29tor31are affected.
๐ VMS Options ๐
These -m options are defined for the VMS implementations ๐ซ:
-mvms-return-codesโ returns VMS condition codes frommain. The default is to return POSIX-style condition (e.g. error) codes ๐๏ธ.-mdebug-main=prefixโ flags the first routine whose name starts withprefixas the main routine for the debugger ๐.-mmalloc64โ defaults to 64-bit memory allocation routines ๐งฎ.-mpointer-size=sizeโ sets the default size of pointers ๐. The possible options forsizeare32orshortfor 32-bit pointers,64orlongfor 64-bit pointers, andnofor supporting only 32-bit pointers. The latter option disablespragma pointer_size.
โญ VxWorks Options โญ
The options in this section are defined for all VxWorks targets ๐ง. Options specific to the target hardware are listed with the other options for that target.
-mrtpโ GCC can generate code for both VxWorks kernels and real time processes (RTPs) ๐. This option switches from the former to the latter. It also defines the preprocessor macro__RTP__.-non-staticโ links an RTP executable against shared libraries rather than static libraries ๐. The options-staticand-sharedcan also be used for RTPs, and-staticis the default.-Bstatic,-Bdynamicโ these get passed down to the linker ๐จ. They're defined for compatibility with Diab.-Xbind-lazyโ enables lazy binding of function calls ๐ด. This option is equivalent to-Wl,-z,nowand is defined for compatibility with Diab.-Xbind-nowโ disables lazy binding of function calls ๐โโ๏ธ. This option is the default and is defined for compatibility with Diab.
๐ x86 Options ๐
These -m options are defined for the x86 family of computers ๐ป.
-march=cpu-typeโ generates instructions for the machine typecpu-type๐ฅ. Unlike-mtune=cpu-type, which merely tunes the generated code for the specifiedcpu-type,-march=cpu-typeallows GCC to generate code that may not run at all on processors other than the one indicated ๐ฌ. Specifying-march=cpu-typeimplies-mtune=cpu-type, except where noted otherwise.
The choices for cpu-type are:
nativeโ selects the CPU to generate code for at compilation time by figuring out the processor type of the compiling machine ๐ฅ๏ธ. Using-march=nativeenables all instruction subsets supported by the local machine (hence the result might not run on different machines). Using-mtune=nativeproduces code optimized for the local machine under the constraints of the selected instruction set.x86-64โ a generic CPU with 64-bit extensions ๐.x86-64-v2,x86-64-v3,x86-64-v4โ these select the corresponding micro-architecture level from the x86-64 psABI ๐. On ABIs other than the x86-64 psABI, they select the same CPU features as the x86-64 psABI documents for that particular micro-architecture level. Since thesecpu-typevalues don't have a corresponding-mtunesetting, using-marchwith them enables generic tuning. You can enable specific tuning with the-mtune=other-cpu-typeoption and an appropriateother-cpu-typevalue ๐๏ธ.i386โ the original Intel i386 CPU ๐ฆ.i486โ the Intel i486 CPU. (No scheduling is implemented for this chip ๐.)i586,pentiumโ the Intel Pentium CPU with no MMX support ๐ผ.lakemontโ the Intel Lakemont MCU, based on the Intel Pentium CPU ๐งฉ.pentium-mmxโ the Intel Pentium MMX CPU, based on the Pentium core with MMX instruction set support ๐น.pentiumproโ the Intel Pentium Pro CPU ๐.i686โ when used with-march, the Pentium Pro instruction set is used, so the code runs on all i686 family chips ๐ซ. When used with-mtune, it has the same meaning asgeneric.pentium2โ the Intel Pentium II CPU, based on the Pentium Pro core with MMX instruction set support ๐ฟ.pentium3,pentium3mโ the Intel Pentium III CPU, based on the Pentium Pro core with MMX and SSE instruction set support ๐.pentium-mโ the Intel Pentium M ๐ป. It's a low-power version of the Intel Pentium III CPU with MMX, SSE and SSE2 instruction set support, and it's used by Centrino notebooks ๐.pentium4,pentium4mโ the Intel Pentium 4 CPU with MMX, SSE and SSE2 instruction set support ๐.prescottโ an improved version of the Intel Pentium 4 CPU with MMX, SSE, SSE2 and SSE3 instruction set support ๐ธ.noconaโ an improved version of the Intel Pentium 4 CPU with 64-bit extensions, MMX, SSE, SSE2 and SSE3 instruction set support ๐.core2โ the Intel Core 2 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support โ.nehalemโ the Intel Nehalem CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 and POPCNT instruction set support ๐.westmereโ the Intel Westmere CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES and PCLMUL instruction set support ๐.
sandybridgeโ ๐ธ Intel Sandy Bridge CPU, so you get 64-bit extensions plus MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AES and PCLMUL instruction set support. โจivybridgeโ ๐ฆ Intel Ivy Bridge CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AES, PCLMUL, FSGSBASE, RDRND and F16C instruction set support. ๐haswellโ ๐ Intel Haswell CPU, slaying with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2 and F16C instruction set support. ๐ฅbroadwellโ ๐ Intel Broadwell CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED ADCX and PREFETCHW instruction set support. ๐skylakeโ ๐ Intel Skylake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC and XSAVES instruction set support. ๐bonnellโ ๐ง Intel Bonnell CPU, a little more chill, with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support. ๐silvermontโ โญ Intel Silvermont CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL and RDRND instruction set support. ๐ซถgoldmontโ ๐ Intel Goldmont CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT and FSGSBASE instruction set support. โจgoldmont-plusโ ๐ธ Intel Goldmont Plus CPU, the glow-up version, with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX and UMIP instruction set support. ๐tremontโ ๐ฆ Intel Tremont CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, UMIP, GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B, CLDEMOTE and WAITPKG instruction set support. ๐ฅknlโ ๐ Intel Knight's Landing CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, PREFETCHWT1, AVX512F, AVX512PF, AVX512ER and AVX512CD instruction set support. ๐knmโ ๐ Intel Knights Mill CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, PREFETCHWT1, AVX512F, AVX512PF, AVX512ER, AVX512CD, AVX5124VNNIW, AVX5124FMAPS and AVX512VPOPCNTDQ instruction set support. ๐skylake-avx512โ ๐ฅ Intel Skylake Server CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ and AVX512CD instruction set support. ๐cannonlakeโ ๐ซถ Intel Cannonlake Server CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA and UMIP instruction set support. ๐ธicelake-clientโ โจ Intel Icelake Client CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ and VAES instruction set support. ๐ฆicelake-serverโ ๐ Intel Icelake Server CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG and WBNOINVD instruction set support. ๐cascadelakeโ ๐ Intel Cascadelake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD and AVX512VNNI instruction set support. ๐cooperlakeโ ๐ง Intel cooperlake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI and AVX512BF16 instruction set support. ๐tigerlakeโ ๐ Intel Tigerlake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT and KEYLOCKER instruction set support. ๐ฅk6โ ๐ธ AMD K6 CPU with MMX instruction set support. Vintage, but iconic. ๐k6-2,k6-3โ ๐ Improved versions of AMD K6 CPU with MMX and 3DNow! instruction set support. โจathlon,athlon-tbirdโ ๐ฆ AMD Athlon CPU with MMX, 3dNOW!, enhanced 3DNow! and SSE prefetch instructions support. ๐athlon-4,athlon-xp,athlon-mpโ ๐ฅ Improved AMD Athlon CPU with MMX, 3DNow!, enhanced 3DNow! and full SSE instruction set support. ๐k8,opteron,athlon64,athlon-fxโ ๐ Processors based on the AMD K8 core with x86-64 instruction set support, including the AMD Opteron, Athlon 64, and Athlon 64 FX processors. (This supersets MMX, SSE, SSE2, 3DNow!, enhanced 3DNow! and 64-bit instruction set extensions.) ๐k8-sse3,opteron-sse3,athlon64-sse3โ ๐ Improved versions of AMD K8 cores with SSE3 instruction set support. ๐amdfam10,barcelonaโ ๐ง CPUs based on AMD Family 10h cores with x86-64 instruction set support. (This supersets MMX, SSE, SSE2, SSE3, SSE4A, 3DNow!, enhanced 3DNow!, ABM and 64-bit instruction set extensions.) ๐ซถbdver1โ โญ CPUs based on AMD Family 15h cores with x86-64 instruction set support. (This supersets FMA4, AVX, XOP, LWP, AES, PCLMUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set extensions.) ๐bdver2โ ๐ฆ AMD Family 15h core based CPUs with x86-64 instruction set support. (This supersets BMI, TBM, F16C, FMA, FMA4, AVX, XOP, LWP, AES, PCLMUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set extensions.) โจbdver3โ ๐ฅ AMD Family 15h core based CPUs with x86-64 instruction set support. (This supersets BMI, TBM, F16C, FMA, FMA4, FSGSBASE, AVX, XOP, LWP, AES, PCLMUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set extensions.) ๐ธbdver4โ ๐ AMD Family 15h core based CPUs with x86-64 instruction set support. (This supersets BMI, BMI2, TBM, F16C, FMA, FMA4, FSGSBASE, AVX, AVX2, XOP, LWP, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set extensions.) ๐znver1โ ๐ซถ AMD Family 17h core based CPUs with x86-64 instruction set support. (This supersets BMI, BMI2, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, and 64-bit instruction set extensions.) ๐znver2โ ๐ AMD Family 17h core based CPUs with x86-64 instruction set support. (This supersets BMI, BMI2, CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, and 64-bit instruction set extensions.) ๐znver3โ ๐ AMD Family 19h core based CPUs with x86-64 instruction set support. (This supersets BMI, BMI2, CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, PKU, VPCLMULQDQ, VAES, and 64-bit instruction set extensions.) ๐งbtver1โ ๐ CPUs based on AMD Family 14h cores with x86-64 instruction set support. (This supersets MMX, SSE, SSE2, SSE3, SSSE3, SSE4A, CX16, ABM and 64-bit instruction set extensions.) ๐btver2โ ๐ฆ CPUs based on AMD Family 16h cores with x86-64 instruction set support. This includes MOVBE, F16C, BMI, AVX, PCLMUL, AES, SSE4.2, SSE4.1, CX16, ABM, SSE4A, SSSE3, SSE3, SSE2, SSE, MMX and 64-bit instruction set extensions. ๐ธwinchip-c6โ ๐ IDT WinChip C6 CPU, dealt in same way as i486 with additional MMX instruction set support. ๐winchip2โ ๐ซถ IDT WinChip 2 CPU, dealt in same way as i486 with additional MMX and 3DNow! instruction set support. โจc3: VIA C3 chip with MMX and 3DNow! support ๐ (ngl no scheduling is implemented for this one)c3-2: VIA C3-2 (Nehemiah/C5XL) with MMX and SSE ๐ธ (no scheduling is implemented here either)c7: VIA C7 (Esther) with MMX, SSE, SSE2 and SSE3 โจ (no scheduling implemented, bestie)samuel-2: VIA Eden Samuel 2 with MMX and 3DNow! ๐ฆ (no scheduling is implemented for this chip)nehemiah: VIA Eden Nehemiah with MMX and SSE ๐ (no scheduling is implemented for this chip)esther: VIA Eden Esther with MMX, SSE, SSE2 and SSE3 ๐ (no scheduling is implemented for this chip)eden-x2: VIA Eden X2 with x86-64, MMX, SSE, SSE2 and SSE3 ๐ง (no scheduling is implemented for this chip)eden-x4: VIA Eden X4 with x86-64, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and AVX2 ๐ (no scheduling is implemented for this chip, it's giving a lot)nano: the generic VIA Nano with x86-64, MMX, SSE, SSE2, SSE3 and SSSE3 ๐ (no scheduling is implemented for this chip)nano-1000: VIA Nano 1xxx with x86-64, MMX, SSE, SSE2, SSE3 and SSSE3 ๐ (no scheduling is implemented for this chip)nano-2000: VIA Nano 2xxx with x86-64, MMX, SSE, SSE2, SSE3 and SSSE3 โญ (no scheduling is implemented for this chip)nano-3000: VIA Nano 3xxx with x86-64, MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 ๐ฅ (no scheduling is implemented for this chip)nano-x2: VIA Nano Dual Core with x86-64, MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 ๐ซถ (no scheduling is implemented for this chip)nano-x4: VIA Nano Quad Core with x86-64, MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 ๐ (no scheduling is implemented for this chip)geode: AMD Geode embedded processor with MMX and 3DNow! ๐ธ
โจ -mtune=cpu-type โจ
Okay so -mtune=cpu-type tells GCC to tune everything that can be tuned in the generated code, except the ABI and the set of available instructions ๐. Picking a specific cpu-type schedules things nicely for that exact chip, but the compiler still won't generate any code that can't run on the default machine type, unless you also use a -march=cpu-type option. For example, if GCC is configured for i686-pc-linux-gnu, then -mtune=pentium4 generates code tuned for Pentium 4 that still runs on i686 machines ๐.
The choices for cpu-type are the same as for -march. On top of that, -mtune has 2 extra choices, and they're iconic ๐:
genericโ produces code optimized for the most common IA32/AMD64/EM64T processors ๐. If you know the CPU your code will run on, use the matching-mtuneor-marchoption instead of-mtune=generic. But if you have no idea what CPU your users will have, this is the one to use ๐ซถ.
As new processors get deployed in the marketplace, the behavior of this option will change. So if you upgrade to a newer version of GCC, the code generation controlled by this option will change to match whatever processors are most common when that GCC version gets released ๐ฆ.
There is no -march=generic option, because -march indicates the instruction set the compiler can use, and there's no generic instruction set that applies to all processors. -mtune, on the other hand, indicates the processor (or, in this case, the collection of processors) the code is optimized for โจ.
intelโ produces code optimized for the most current Intel processors, which for this version of GCC are Haswell and Silvermont ๐ . If you know the CPU your code will run on, use the matching-mtuneor-marchoption instead of-mtune=intel. But if you want your application to perform better on both Haswell and Silvermont, this is your option ๐ฅ.
As new Intel processors get deployed, the behavior of this option will change. So if you upgrade to a newer GCC, the code generation controlled by this option will reflect the most current Intel processors at the time that version of GCC is released ๐ธ.
There is no -march=intel option, because -march indicates the instruction set the compiler can use, and there's no common instruction set that applies to all processors. -mtune indicates the processor (or collection of processors) the code is optimized for, which is the vibe here ๐.
โจ -mcpu=cpu-type โจ
This is a deprecated synonym for -mtune. Bestie, just use -mtune instead ๐.
โจ -mfpmath=unit โจ
This option generates floating-point arithmetic for the selected unit. The choices for unit are:
387โ uses the standard 387 floating-point coprocessor, which is on the majority of chips and emulated otherwise ๐ง. Code compiled this way runs almost everywhere. The temporary results are computed in 80-bit precision instead of the precision set by the type, so you can get slightly different results than most other chips. See-ffloat-storefor a more detailed description ๐.
This is the default choice for non-Darwin x86-32 targets ๐.
sseโ uses the scalar floating-point instructions from the SSE instruction set ๐. This set is supported by Pentium III and newer chips, and on the AMD side by Athlon-4, Athlon XP and Athlon MP chips ๐ฆ. The earlier version of SSE only supports single-precision arithmetic, so double and extended-precision arithmetic are still done with 387 ๐ซถ. A later version, which only shows up in Pentium 4 and AMD x86-64 chips, supports double-precision arithmetic too โจ.
For the x86-32 compiler, you must use -march=cpu-type, -msse or -msse2 switches to enable the SSE extensions and make this option work ๐. For the x86-64 compiler, these extensions are enabled by default ๐.
The resulting code should be considerably faster in most cases and avoid the numerical instability problems of 387 code. But it may break some existing code that expects temporaries to be 80 bits ๐.
This is the default choice for the x86-64 compiler, for Darwin x86-32 targets, and for x86-32 targets with the SSE2 instruction set when -ffast-math is enabled ๐
.
sse,387,sse+387,bothโ attempts to use both instruction sets at once ๐ฅ. This effectively doubles the number of available registers, and on chips with separate execution units for 387 and SSE, it doubles the execution resources too โญ. Use this option with care, because it's still experimental. The GCC register allocator doesn't model separate functional units well, which leads to unstable performance ๐.
โจ -masm=dialect โจ
This outputs assembly instructions using the selected dialect, and it also affects which dialect gets used for basic asm and extended asm ๐ง. The supported choices, in dialect order, are att or intel. The default is att. Darwin does not support intel ๐.
โจ -mieee-fp / -mno-ieee-fp โจ
These control whether or not the compiler uses IEEE floating-point comparisons ๐ธ. IEEE comparisons correctly handle the case where the result of a comparison is unordered ๐.
โจ -m80387 / -mhard-float โจ
This generates output containing 80387 instructions for floating point ๐.
โจ -mno-80387 / -msoft-float โจ
This generates output containing library calls for floating point instead ๐ฆ.
Warning: the requisite libraries are not part of GCC ๐ญ. Normally the facilities of the machine's usual C compiler get used, but that can't be done directly in cross-compilation. You have to make your own arrangements to provide suitable library functions for cross-compilation, no shortcuts ๐.
On machines where a function returns floating-point results in the 80387 register stack, some floating-point opcodes may still be emitted even if -msoft-float is used ๐.
โจ -mno-fp-ret-in-387 โจ
This stops the compiler from using the FPU registers for function return values ๐.
The usual calling convention has functions return float and double values in an FPU register, even when there's no FPU at all. The idea is that the operating system should emulate the FPU ๐ง.
-mno-fp-ret-in-387 instead makes those values get returned in ordinary CPU registers ๐ซถ.
โจ -mno-fancy-math-387 โจ
Some 387 emulators don't support the sin, cos and sqrt instructions for the 387 ๐ญ. Specify this option to avoid generating those instructions ๐
.
This option gets overridden when -march indicates that the target CPU always has an FPU, so the instruction doesn't need emulating โจ. These instructions also aren't generated unless you use the -funsafe-math-optimizations switch too โญ.
โจ -malign-double / -mno-align-double โจ
These control whether GCC aligns double, long double, and long long variables on a two-word boundary or a one-word boundary ๐. Aligning double variables on a two-word boundary produces code that runs somewhat faster on a Pentium, at the expense of more memory ๐.
On x86-64, -malign-double is enabled by default ๐ฆ.
Warning: if you use the -malign-double switch, structures containing the above types are aligned differently than the published application binary interface specifications for x86-32. They are not binary compatible with structures in code compiled without that switch ๐๐.
โจ -m96bit-long-double / -m128bit-long-double โจ
These switches control the size of the long double type ๐. The x86-32 application binary interface specifies the size as 96 bits, so -m96bit-long-double is the default in 32-bit mode ๐.
Okay so modern chips (Pentium and newer) really want long double lined up on an 8- or 16-byte boundary ๐ซถ but inside arrays and structs that follow the ABI, that's just not happening ๐ญ. So -m128bit-long-double pads each long double with an extra 32-bit zero to get it onto a 16-byte boundary โจ.
On x86-64, -m128bit-long-double is the default, because that ABI says long double gets 16-byte alignment ๐.
Ngl, neither of these flags gives you any extra precision past the x87 standard of 80 bits for a long double ๐
Warning: if you override the default for your target ABI, you change the size of structures and arrays containinglong doublevariables, and you also change the function calling convention for functions that takelong double. That means the code isn't binary-compatible with code compiled without that switch ๐
-mlong-double-64,-mlong-double-80,-mlong-double-128โ these three control how big thelong doubletype is ๐.-mlong-double-64makes it equivalent todouble(and it's the default for the 32-bit Bionic C library ๐ธ).-mlong-double-128makes it equivalent to__float128(and that's the default for the 64-bit Bionic C library ๐ฆ).
Warning: if you override the default for your target ABI, you change the size of structures and arrays containinglong doublevariables, and you also change the function calling convention for functions that takelong double. That means the code isn't binary-compatible with code compiled without that switch ๐
-malign-data=typeโ this one decides how GCC aligns variables ๐งฉ. The supported values for type arecompat, which uses the increased alignment that's compatible with GCC 4.8 and earlier;abi, which uses the alignment value from the psABI; andcacheline, which uses increased alignment to match the cache line size.compatis the default, so it's the main character unless you say otherwise ๐.-mlarge-data-threshold=thresholdโ when-mcmodel=mediumis on, data objects bigger than threshold get tossed into the large data section ๐ฆ. This value has to be the same across every object linked into the binary, and it defaults to65535๐ข.-mrtdโ this swaps in a different function-calling convention ๐. Functions that take a fixed number of arguments return with theret numinstruction, which pops their arguments on the way out. That saves one instruction in the caller, since the caller doesn't have to pop them anymore โจ.
You can make one specific function use this calling sequence with the function attribute stdcall. You can also override -mrtd for a function by using the function attribute cdecl ๐.
Warning: this calling convention is incompatible with the one normally used on Unix, so you can't use it if you need to call libraries compiled with the Unix compiler ๐ You must also provide function prototypes for every function that takes a variable number of arguments (including printf). If you don't, incorrect code gets generated for calls to those functions ๐ญ On top of that, seriously incorrect code results if you call a function with too many arguments. Normally, extra arguments are harmlessly ignored, but not here ๐
-mregparm=numโ this controls how many registers get used to pass integer arguments ๐ง . By default, no registers are used for passing arguments, and at most 3 registers can be used. You can control this for one specific function with the function attributeregparm๐ฆ.
Warning: if you use this switch and num is nonzero, then you must build all modules with the same value, including any libraries. That includes the system libraries and startup modules ๐จ
-msseregparmโ this uses SSE register passing conventions forfloatanddoublearguments and return values โก. You can control this for a specific function with the function attributesseregparm๐.
Warning: if you use this switch, you must build all modules with the same value, including any libraries. That includes the system libraries and startup modules ๐จ
-mvect8-ret-in-memโ returns 8-byte vectors in memory instead of MMX registers ๐งบ. This is the default on VxWorks, so it matches the ABI of the Sun Studio compilers until version 12. Only use this option if you need to stay compatible with existing code made by those older compiler versions or older versions of GCC ๐ฐ๏ธ.-mpc32,-mpc64,-mpc80โ these set the 80387 floating-point precision to 32, 64 or 80 bits ๐๏ธ. With-mpc32, the significands of floating-point results get rounded to 24 bits (single precision). With-mpc64, they get rounded to 53 bits (double precision). With-mpc80, they get rounded to 64 bits (extended double precision), which is the default ๐ .
When you use one of these, higher-precision floating-point operations aren't available to the programmer unless you set the FPU control word yourself ๐ง.
Setting the rounding to less than the default 80 bits can speed some programs up by 2% or more ๐๏ธ. But heads up: some math libraries assume extended-precision (80-bit) floating-point operations are on by default. Routines in those libraries could lose a lot of accuracy, typically through so-called "catastrophic cancellation," when this option sets the precision to less than extended precision ๐ฑ.
-mstackrealignโ this realigns the stack at entry ๐ช. On x86, it generates an alternate prologue and epilogue that realigns the run-time stack if it's needed. That lets legacy code that keeps 4-byte stack alignment play nicely with modern code that keeps 16-byte stack alignment for SSE compatibility ๐ซถ. See also the attributeforce_align_arg_pointer, which works on individual functions โจ.-mpreferred-stack-boundary=numโ this tries to keep the stack boundary aligned to a 2 raised to num byte boundary ๐. If you don't specify-mpreferred-stack-boundary, the default is4, which is 16 bytes or 128 bits ๐.
Warning: when you generate code for the x86-64 architecture with SSE extensions disabled,-mpreferred-stack-boundary=3can be used to keep the stack boundary aligned to an 8-byte boundary. But the x86-64 ABI requires 16-byte stack alignment, so this is ABI incompatible ๐ โโ๏ธ It's only meant for a controlled environment where stack space is a seriously important limitation. This option leads to wrong code when functions compiled with 16-byte stack alignment (like functions from a standard library) get called with a misaligned stack. In that case, SSE instructions may cause misaligned memory access traps ๐ Variable arguments are also handled incorrectly for 16-byte aligned objects (including x87long doubleand__int128), which leads to wrong results ๐ญ You must build all modules with-mpreferred-stack-boundary=3, including any libraries. That includes the system libraries and startup modules ๐จ
-mincoming-stack-boundary=numโ this tells GCC to assume the incoming stack is aligned to a 2 raised to num byte boundary ๐ฅ. If you don't specify-mincoming-stack-boundary, the one specified by-mpreferred-stack-boundarygets used instead.
On Pentium and Pentium Pro, double and long double values should be aligned to an 8-byte boundary (see -malign-double), or you'll take some serious run-time performance penalties ๐ข. On Pentium III, the Streaming SIMD Extension (SSE) data type __m128 may not work properly if it isn't 16-byte aligned ๐.
To make sure these values are aligned properly on the stack, the stack boundary has to be as aligned as whatever value needs the most alignment on the stack. Also, every function has to be generated so it keeps the stack aligned. So calling a function compiled with a higher preferred stack boundary from a function compiled with a lower one most likely misaligns the stack ๐ฌ It's recommended that libraries which use callbacks always use the default setting ๐ซถ.
This extra alignment does eat up extra stack space and generally increases code size. Code that's sensitive to stack space usage, like embedded systems and operating system kernels, may want to reduce the preferred alignment to -mpreferred-stack-boundary=2 ๐ง.
- The big ISA squad โ these switches enable the use of a whole crew of instructions ๐. Here's the full list, all of them, no skipping:
-mmmx
-msse
-msse2
-msse3
-mssse3
-msse4
-msse4a
-msse4.1
-msse4.2
-mavx
-mavx2
-mavx512f
-mavx512pf
-mavx512er
-mavx512cd
-mavx512vl
-mavx512bw
-mavx512dq
-mavx512ifma
-mavx512vbmi
-msha
-maes
-mpclmul
-mclflushopt
-mclwb
-mfsgsbase
-mptwrite
-mrdrnd
-mf16c
-mfma
-mpconfig
-mwbnoinvd
-mfma4
-mprfchw
-mrdpid
-mprefetchwt1
-mrdseed
-msgx
-mxop
-mlwp
-m3dnow
-m3dnowa
-mpopcnt
-mabm
-madx
-mbmi
-mbmi2
-mlzcnt
-mfxsr
-mxsave
-mxsaveopt
-mxsavec
-mxsaves
-mrtm
-mhle
-mtbm
-mmwaitx
-mclzero
-mpku
-mavx512vbmi2
-mavx512bf16
-mgfni
-mvaes
-mwaitpkg
-mvpclmulqdq
-mavx512bitalg
-mmovdiri
-mmovdir64b
-menqcmd
-mavx512vpopcntdq
-mavx512vp2intersect
-mavx5124fmaps
-mavx512vnni
-mavx5124vnniw
-mcldemote
These switches enable the use of instructions in the MMX, SSE, SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA, AES, PCLMUL, CLFLUSHOPT, CLWB, FSGSBASE, PTWRITE, RDRND, F16C, FMA, PCONFIG, WBNOINVD, FMA4, PREFETCHW, RDPID, PREFETCHWT1, RDSEED, SGX, XOP, LWP, 3DNow!, enhanced 3DNow!, POPCNT, ABM, ADX, BMI, BMI2, LZCNT, FXSR, XSAVE, XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2, GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, or CLDEMOTE extended instruction sets. Each one has a matching -mno- option to switch off those instructions ๐
โโ๏ธ
These extensions also show up as built-in functions! Check out x86 Built-in Functions for the details on which functions get enabled and disabled by these switches ๐ง๐
Okay so if you want SSE/SSE2 instructions generated automatically from floating-point code (instead of the 387 ones), go check out -mfpmath=sse ๐ฆ
ngl GCC kinda depresses SSEx instructions ๐ญ when -mavx is on. Instead, it spits out brand-new AVX instructions, or AVX equivalents for all the SSEx instructions when needed ๐
These options let GCC use these extended instructions in the generated code, even without -mfpmath=sse โจ Bestie, heads up: apps that do run-time CPU detection need to compile separate files for each supported architecture, using the right flags ๐ซถ And the file with the CPU detection code specifically should be compiled without these options ๐
-mdump-tune-featuresโ GCC dumps the names of the x86 performance tuning features and their default settings ๐ You can use those names in-mtune-ctrl=feature-list.-mtune-ctrl=feature-listโ fine-grain control over x86 code generation features ๐๏ธfeature-listis a comma-separated list of feature names. See also-mdump-tune-features. A feature gets turned on if it isn't preceded by^, and turned off if it is. This one is really meant for GCC developers ๐งโ๐ป
โ ๏ธ Bestie, be careful! Using -mtune-ctrl=feature-list may lead to code paths that aren't covered by testing, and it can potentially result in compiler ICEs or runtime errors ๐
-mno-defaultโ turns off all tunable features ๐ See also-mtune-ctrl=feature-listand-mdump-tune-features.-mcldโ GCC emits acldinstruction in the prologue of functions that use string instructions ๐งน String instructions depend on theDFflag to pick autoincrement or autodecrement mode. The ABI saysDFgets cleared on function entry, but some operating systems don't clear it in their exception dispatchers ๐ฌ So the exception handler can be invoked withDFset, which leads to the wrong direction mode when string instructions are used. This option can be enabled by default on 32-bit x86 targets by configuring GCC with the--enable-cldconfigure option. Generation ofcldinstructions can be suppressed with the-mno-cldcompiler option in this case.-mvzeroupperโ emits avzeroupperinstruction before control flow leaves the function ๐งผ This minimizes the AVX to SSE transition penalty, and also removes unnecessaryzeroupperintrinsics.-mprefer-avx128โ uses 128-bit AVX instructions instead of 256-bit AVX instructions in the auto-vectorizer ๐-mprefer-vector-width=optโ usesopt-bit vector width in instructions instead of the default on the selected platform ๐noneโ no extra limits on GCC beyond what the selected platform already defines128โ prefer 128-bit vector width256โ prefer 256-bit vector width512โ prefer 512-bit vector width
-mcx16โ enablesCMPXCHG16Binstructions in 64-bit code ๐ These do compare-and-exchange operations on 16-byte aligned 128-bit objects, which is super useful for atomic updates of data structures bigger than one machine word ๐ The compiler uses this instruction to implement__syncBuiltins. For__atomicBuiltins operating on 128-bit integers, though, a library call is always used.-msahfโ enables generation ofSAHFinstructions in 64-bit code ๐ง Early Intel Pentium 4 CPUs with Intel 64 support, before the Pentium 4 G1 step in December 2005, lacked theLAHFandSAHFinstructions that AMD64 supports. These are load and store instructions, respectively, for certain status flags. In 64-bit mode,SAHFis used to optimize thefmod,drem, andremainderbuilt-in functions; see Other Builtins for details.-mmovbeโ enables use of themovbeinstruction to implement__builtin_bswap32and__builtin_bswap64๐-mshstkโ enables the shadow stack built-in functions from x86 Control-flow Enforcement Technology (CET) ๐ก๏ธ-mcrc32โ makes the built-in functions__builtin_ia32_crc32qi,__builtin_ia32_crc32hi,__builtin_ia32_crc32siand__builtin_ia32_crc32digenerate thecrc32machine instruction ๐งฎ-mrecipโ enables use ofRCPSSandRSQRTSSinstructions (and their vectorized variantsRCPPSandRSQRTPS) with an additional Newton-Raphson step to increase precision, instead ofDIVSSandSQRTSS(and their vectorized variants) for single-precision floating-point arguments ๐ฏ These instructions are only generated when-funsafe-math-optimizationsis enabled together with-ffinite-math-onlyand-fno-trapping-math. Note that while the throughput of the sequence is higher than the throughput of the non-reciprocal instruction, the precision of the sequence can be decreased by up to 2 ulp (i.e. the inverse of 1.0 equals0.99999994).
Note that GCC implements 1.0f/sqrtf(x) in terms of RSQRTSS (or RSQRTPS) already with -ffast-math (or the above option combination), and doesn't need -mrecip.
Also note that GCC emits the above sequence with an additional Newton-Raphson step for vectorized single-float division and vectorized sqrtf(x) already with -ffast-math (or the above option combination), and doesn't need -mrecip.
-mrecip=optโ controls which reciprocal estimate instructions may be used ๐๏ธoptis a comma-separated list of options, and any of them can be preceded by a!to invert the option:allโ enable all estimate instructionsdefaultโ enable the default instructions, equivalent to-mrecipnoneโ disable all estimate instructions, equivalent to-mno-recipdivโ enable the approximation for scalar divisionvec-divโ enable the approximation for vectorized divisionsqrtโ enable the approximation for scalar square rootvec-sqrtโ enable the approximation for vectorized square root
So, for example, -mrecip=all,!sqrt enables all of the reciprocal approximations, except for square root โจ
-mveclibabi=typeโ specifies the ABI type to use for vectorizing intrinsics using an external library ๐ Supported values fortypearesvmlfor the Intel short vector math library andacmlfor the AMD math core library. To use this option, both-ftree-vectorizeand-funsafe-math-optimizationshave to be enabled, and an SVML or ACML ABI-compatible library must be specified at link time.
GCC currently emits calls to vmldExp2, vmldLn2, vmldLog102, vmldPow2, vmldTanh2, vmldTan2, vmldAtan2, vmldAtanh2, vmldCbrt2, vmldSinh2, vmldSin2, vmldAsinh2, vmldAsin2, vmldCosh2, vmldCos2, vmldAcosh2, vmldAcos2, vmlsExp4, vmlsLn4, vmlsLog104, vmlsPow4, vmlsTanh4, vmlsTan4, vmlsAtan4, vmlsAtanh4, vmlsCbrt4, vmlsSinh4, vmlsSin4, vmlsAsinh4, vmlsAsin4, vmlsCosh4, vmlsCos4, vmlsAcosh4 and vmlsAcos4 for the corresponding function type when -mveclibabi=svml is used, and __vrd2_sin, __vrd2_cos, __vrd2_exp, __vrd2_log, __vrd2_log2, __vrd2_log10, __vrs4_sinf, __vrs4_cosf, __vrs4_expf, __vrs4_logf, __vrs4_log2f, __vrs4_log10f and __vrs4_powf for the corresponding function type when -mveclibabi=acml is used.
-mabi=nameโ generates code for the specified calling convention ๐ Permissible values aresysvfor the ABI used on GNU/Linux and other systems, andmsfor the Microsoft ABI. The default is the Microsoft ABI when targeting Microsoft Windows, and the SysV ABI on all other systems. You can control this for specific functions with the function attributesms_abiandsysv_abi๐-mforce-indirect-callโ forces all calls to functions to be indirect ๐ฆ This is useful with Intel Processor Trace, where it generates more precise timing information for function calls.-mmanual-endbrโ inserts anENDBRinstruction at function entry only via thecf_checkfunction attribute ๐ This is useful when used with the option-fcf-protection=branchto controlENDBRinsertion at the function entry.-mcall-ms2sysv-xloguesโ due to differences in 64-bit ABIs, any Microsoft ABI function that calls a System V ABI function must considerRSI,RDIandXMM6-15as clobbered (aka overwritten, bestie) ๐ง By default, the code for saving and restoring these registers is emitted inline, which makes the prologues and epilogues pretty lengthy. Using-mcall-ms2sysv-xloguesemits prologues and epilogues that use stubs in the static portion oflibgccto do these saves and restores. That reduces function size at the cost of a few extra instructions โจ-mtls-dialect=typeโ generates code to access thread-local storage using thegnuorgnu2conventions ๐งตgnuis the conservative default.gnu2is more efficient, but it may add compile- and run-time requirements that cannot be satisfied on all systems โ ๏ธ-mpush-args,-mno-push-argsโ uses PUSH operations to store outgoing parameters ๐ฅ This method is shorter and usually equally fast as the method using SUB/MOV operations, and it is enabled by default. In some cases, disabling it may improve performance because of improved scheduling and reduced dependencies.-maccumulate-outgoing-argsโ if enabled, the maximum amount of space required for outgoing arguments is computed in the function prologue ๐๏ธ This is faster on most modern CPUs because of reduced dependencies, improved scheduling, and reduced stack usage when the preferred stack boundary is not equal to 2. The drawback is a notable increase in code size. This switch implies-mno-push-args.-mthreadsโ supports thread-safe exception handling on MinGW ๐งต Programs that rely on thread-safe exception handling must compile and link all code with the-mthreadsoption. When compiling,-mthreadsdefines-D_MT. When linking, it links in a special thread helper library,-lmingwthrd, which cleans up per-thread exception-handling data.-mms-bitfields,-mno-ms-bitfieldsโ enables or disables bit-field layout compatible with the native Microsoft Windows compiler ๐ช
okay so if you slap "packed" on a struct, or use bit-fields, the Microsoft ABI might lay that struct out totally differently from how GCC does it ๐ this is lowkey a big deal, especially when you're moving packed data between functions compiled with GCC and the native Microsoft compiler (through a function call or as data in a file), because you may need to access either format ๐ซถ
This option is enabled by default for Microsoft Windows targets ๐ช but you can control it locally with variable or type attributes. For the full tea, check out x86 Variable Attributes and x86 Type Attributes ๐
The Microsoft struct layout algorithm is pretty simple โจ except for bit-field packing ๐ Here's how it decides the padding and alignment of struct members, plus whether a bit-field can straddle a storage-unit boundary:
- Structure members are stored in the order they're declared ๐ the first member sits at the lowest memory address and the last member sits at the highest ๐ง
- Every data object has an alignment requirement. For everything except structs, unions, and arrays, it's whichever is less: the size of the object, or the current packing size (set with the "aligned" attribute or the "pack" pragma). For structs, unions, and arrays, it's the largest alignment requirement of any of its members. Every object gets an offset so that:
offset % alignment_requirement == 0
- Adjacent bit-fields get packed into the same 1-, 2-, or 4-byte allocation unit if their integral types are the same size, AND the next bit-field fits in the current allocation unit without crossing the boundary imposed by the bit-fields' common alignment requirements ๐
MSVC interprets zero-length bit-fields in the following ways ๐คฏ
- If a zero-length bit-field is inserted between two bit-fields that would normally be coalesced, those bit-fields are not coalesced anymore. For example:
struct
{
unsigned long bf_1 : 12;
unsigned long : 0;
unsigned long bf_2 : 12;
} t1;
The size of "t1" is 8 bytes with the zero-length bit-field. If the zero-length bit-field were removed, "t1"'s size would be 4 bytes.
- If a zero-length bit-field is inserted after a bit-field, "foo", and the zero-length bit-field's alignment is greater than the member that follows it, "bar", then "bar" gets aligned as the type of the zero-length bit-field. For example:
struct
{
char foo : 4;
short : 0;
char bar;
} t2;
struct
{
char foo : 4;
short : 0;
double bar;
} t3;
For "t2", "bar" is placed at offset 2 instead of offset 1, so the size of "t2" is 4 ๐ซ For "t3", the zero-length bit-field doesn't affect the alignment of "bar" or, as a result, the size of the struct.
Taking this into account, it's important to note the following:
- If a zero-length bit-field follows a normal bit-field, the type of that zero-length bit-field may affect the alignment of the whole structure. For example, "t2" has a size of 4 bytes, since the zero-length bit-field follows a normal bit-field and is of type short.
- Even if a zero-length bit-field is not followed by a normal bit-field, it can still affect the alignment of the structure:
struct
{
char foo : 6;
long : 0;
} t4;
Here, "t4" takes up 4 bytes.
- Zero-length bit-fields following non-bit-field members are ignored:
struct
{
char foo;
long : 0;
char bar;
} t5;
Here, "t5" takes up 2 bytes. Ignored, bestie ๐
-mno-align-stringopsโ don't align the destination of inlined string operations ๐ธ this makes code smaller and can speed things up if the destination is already aligned but GCC doesn't know that.-minline-all-stringopsโ by default GCC only inlines string operations when the destination is known to be aligned to at least a 4-byte boundary. This turns on way more inlining (bigger code, but it may boost shortmemcpyandmemsetcalls ๐). It also enables inline expansion of "strlen" for all pointer alignments.-minline-stringops-dynamicallyโ for string operations of unknown size, it adds run-time checks: inline code for small blocks, and a library call for large ones ๐ง-mstringop-strategy=algโ overrides GCC's internal heuristic for which algorithm to use when inlining string operations. The allowed values foralgare:rep_byte,rep_4byte,rep_8byteโ expand using the i386 "rep" prefix of the specified size.byte_loop,loop,unrolled_loopโ expand into an inline loop.libcallโ always use a library call ๐
-mmemcpy-strategy=strategyโ overrides the heuristic that decides whether__builtin_memcpygets inlined, and which inline algorithm to use when the expected copy size is known.strategyis a comma-separated list ofalg:max_size:dest_aligntriplets.algis one of the values from-mstringop-strategy, andmax_sizeis the biggest byte size that inline algorithmalgis allowed for. The last triplet must havemax_sizeset to-1. Themax_sizevalues in the list have to be in increasing order. The minimal byte size foralgis 0 for the first triplet, andmax_size + 1of the preceding range for the rest ๐-mmemset-strategy=strategyโ same vibe as-mmemcpy-strategy=, except it controls__builtin_memsetexpansion ๐งน-momit-leaf-frame-pointerโ don't keep the frame pointer in a register for leaf functions. This skips the instructions that save, set up, and restore frame pointers, and frees up an extra register in leaf functions. The option-fomit-leaf-frame-pointerremoves the frame pointer for leaf functions too, but it might make debugging harder ๐-mtls-direct-seg-refs,-mno-tls-direct-seg-refsโ controls whether TLS variables can be accessed with offsets from the TLS segment register (%gsfor 32-bit,%fsfor 64-bit), or whether the thread base pointer has to be added. Whether that's valid depends on the operating system, and on whether it maps the segment to cover the entire TLS area ๐บ๏ธ
For systems that use the GNU C Library, the default is on โ
-msse2avx,-mno-sse2avxโ tells the assembler to encode SSE instructions with the VEX prefix โก The option-mavxturns this on by default.-mfentry,-mno-fentryโ if profiling is active (-pg), put the profiling counter call before the prologue. Note: on x86 architectures, the attribute "ms_hook_prologue" isn't possible at the moment for-mfentryand-pg๐ โโ๏ธ-mrecord-mcount,-mno-record-mcountโ if profiling is active (-pg), generate a__mcount_locsection that holds pointers to each profiling call. This is super useful for automatically patching (and patching out) calls ๐ฉน-mnop-mcount,-mno-nop-mcountโ if profiling is active (-pg), generate the calls to the profiling functions as NOPs. This is handy when they should get patched in later, dynamically. This is likely only useful together with-mrecord-mcount๐งฉ-minstrument-return=typeโ instruments function exit in-pg -mfentryinstrumented functions by calling the specified function. This only instruments true returns ending withret, not sibling calls ending with a jump. Valid types arenone(don't instrument),call(generate a call to__return__), ornop5(generate a 5 byte nop) ๐-mrecord-return,-mno-record-returnโ generates a__return_locsection pointing to all the return instrumentation code ๐-mfentry-name=nameโ sets the name of the__fentry__symbol that gets called at function entry for-pg -mfentryfunctions ๐ท๏ธ-mfentry-section=nameโ sets the name of the section where-mrecord-mcountcalls get recorded (default__mcount_loc) ๐-mskip-rax-setup,-mno-skip-rax-setupโ when generating code for the x86-64 architecture with SSE extensions disabled,-mskip-rax-setupcan skip setting up the RAX register when no variable arguments are passed in vector registers ๐ฆ
โ ๏ธ Warning: the RAX register is used to avoid unnecessarily saving vector registers on the stack when passing variable arguments, so the impacts of this option are that callees may waste some stack space, misbehave, or jump to a random location. GCC 4.4 or newer doesn't have those issues, regardless of the RAX register value.
-m8bit-idiv,-mno-8bit-idivโ on some processors, like Intel Atom, 8-bit unsigned integer divide is way faster than 32-bit/64-bit integer divide ๐๏ธ This option generates a run-time check. If both the dividend and the divisor are within the range of 0 to 255, 8-bit unsigned integer divide is used instead of 32-bit/64-bit integer divide.-mavx256-split-unaligned-load,-mavx256-split-unaligned-storeโ splits 32-byte AVX unaligned loads and stores ๐ช-mstack-protector-guard=guard,-mstack-protector-guard-reg=reg,-mstack-protector-guard-offset=offsetโ generates stack protection code using a canary atguard. The supported locations areglobal(for a global canary) ortls(for a per-thread canary in the TLS block, which is the default) ๐ก๏ธ This option only has an effect when-fstack-protectoror-fstack-protector-allis specified.
Okay so with that second route, the options -mstack-protector-guard-reg=reg and -mstack-protector-guard-offset=offset get to decide which segment register (%fs or %gs) is the base for reading the canary ๐ง, and how far from that base to read. If you don't pick anything, you get whatever the relevant ABI says. Iconic. ๐
-mgeneral-regs-onlyโ Only use the general-purpose registers. The compiler is banned from touching floating-point, vector, mask, and bound registers, so no sneaky extras ๐ฆ-mindirect-branch=choiceโ Converts indirect call and jump based onchoice. The default iskeep, which leaves indirect call and jump totally unmodified ๐ธthunkturns them into call and return thunks.thunk-inlineturns them into inlined call and return thunks.thunk-externturns them into external call and return thunks that live in a separate object file. You can also control this for one specific function with the function attribute"indirect_branch"๐
๐จ Heads up:-mcmodel=largeis incompatible with-mindirect-branch=thunkand-mindirect-branch=thunk-extern, since the thunk function may not be reachable in the large code model.
Note that -mindirect-branch=thunk-extern is compatible with -fcf-protection=branch, since the external thunk can be made to enable control-flow check โจ
-mfunction-return=choiceโ Converts function return based onchoice. The default iskeep, which keeps function return unmodified ๐thunkconverts function return to call and return thunk.thunk-inlineconverts it to an inlined call and return thunk.thunk-externconverts it to an external call and return thunk provided in a separate object file. You can control this for one specific function with the function attribute"function_return"๐
Note that -mindirect-return=thunk-extern is compatible with -fcf-protection=branch, since the external thunk can be made to enable control-flow check ๐ซถ
๐จ Heads up:-mcmodel=largeis incompatible with-mfunction-return=thunkand-mfunction-return=thunk-extern, since the thunk function may not be reachable in the large code model.
-mindirect-branch-registerโ Forces indirect call and jump to go through a register ๐ฅ-mharden-sls=choiceโ Generates code that mitigates straight line speculation (SLS), based onchoice๐ก๏ธ The default isnone, which disables all SLS hardening.returnturns on SLS hardening for function returns.indirect-jmpturns it on for indirect jumps.allturns on every SLS hardening option ๐-mindirect-branch-cs-prefixโ Adds a CS prefix tocallandjmpgoing to an indirect thunk, where the branch target is in ther8-r15registers. This makes the call and jmp instructions 6 bytes long, so they can be swapped at run-time forlfence; call *%r8-r15orlfence; jmp *%r8-r15๐
These -m switches are supported in addition to the above on x86-64 processors in 64-bit environments.
Pick one of these to set the 16-bit, 32-bit, or 64-bit environment you're building for ๐
-m32โ Setsint,long, and pointer types to 32 bits, and generates code that runs in 32-bit mode ๐-m64โ Setsintto 32 bits andlongand pointer types to 64 bits, and generates code for the x86-64 architecture ๐ For Darwin only,-m64also turns off the-fno-picand-mdynamic-no-picoptions ๐-mx32โ Setsint,long, and pointer types to 32 bits, and generates code for the x86-64 architecture ๐ฆ-m16โ Same as-m32, except it outputs the.code16gccassembly directive at the beginning of the assembly output, so the binary can run in 16-bit mode ๐งธ-miamcuโ Generates code that conforms to the Intel MCU psABI. It requires-m32to be turned on ๐ท-mno-red-zoneโ Do not use a so-called "red zone" for x86-64 code. The red zone is mandated by the x86-64 ABI. It's a 128-byte area beyond the stack pointer that signal or interrupt handlers don't touch, so it can be used for temporary data without adjusting the stack pointer. This flag turns that red zone off ๐-mcmodel=smallโ Generates code for the small code model. The program and its symbols must be linked in the lower 2 GB of the address space. Pointers are 64 bits. Programs can be statically or dynamically linked. This is the default code model ๐-mcmodel=kernelโ Generates code for the kernel code model. The kernel runs in the negative 2 GB of the address space. This model has to be used for Linux kernel code ๐ง-mcmodel=mediumโ Generates code for the medium model. The program is linked in the lower 2 GB of the address space, and small symbols are placed there too. Symbols with sizes larger than-mlarge-data-thresholdare put into large data or BSS sections and can be located above 2GB. Programs can be statically or dynamically linked ๐-mcmodel=largeโ Generates code for the large model. This model makes no assumptions about addresses and sizes of sections ๐-maddress-mode=longโ Generates code for long address mode. This is only supported for 64-bit and x32 environments, and it's the default address mode for 64-bit environments ๐-maddress-mode=shortโ Generates code for short address mode. This is only supported for 32-bit and x32 environments, and it's the default address mode for 32-bit and x32 environments ๐ฆ
โจ x86 Windows Options โจ
These additional options are available for Microsoft Windows targets ๐ช
-mconsoleโ Generates a console application by telling the linker to set the PE header subsystem type required for console applications. This option is available for Cygwin and MinGW targets, and it's enabled by default on those targets ๐ป-mdllโ Available for Cygwin and MinGW targets. Generates a DLL, which is a dynamic link library, and enables selection of the required runtime startup object and entry point ๐งฉ-mnop-fun-dllimportโ Available for Cygwin and MinGW targets. The"dllimport"attribute gets ignored ๐ โโ๏ธ-mthreadโ Available for MinGW targets. Uses MinGW-specific thread support ๐งต-municodeโ Available for MinGW-w64 targets. Predefines the"UNICODE"preprocessor macro and chooses Unicode-capable runtime startup code ๐-mwin32โ Available for Cygwin and MinGW targets. Sets the typical Microsoft Windows predefined macros in the pre-processor, but doesn't influence the choice of runtime library or startup code ๐ช-mwindowsโ Available for Cygwin and MinGW targets. Generates a GUI application by telling the linker to set the PE header subsystem type appropriately ๐ชโจ-fno-set-stack-executableโ Available for MinGW targets. The executable flag for the stack used by nested functions isn't set. This is necessary for binaries running in kernel mode of Microsoft Windows, since the User32 API (used to set executable privileges) isn't available there ๐ซ-fwritable-relocated-rdataโ Available for MinGW and Cygwin targets. Relocated data in a read-only section gets put into the".data"section. This is necessary for older runtimes that don't support modifying".rdata"sections for pseudo-relocation ๐ง-mpe-aligned-commonsโ Available for Cygwin and MinGW targets. Uses the GNU extension to the PE file format that permits correct alignment of COMMON variables when generating code. It's enabled by default if GCC detects that the target assembler found during configuration supports the feature ๐
See also under x86 Options for standard options.
โจ Xstormy16 Options โจ
These options are defined for Xstormy16 ๐ฉ๏ธ
-msimโ Chooses startup files and a linker script suitable for the simulator ๐ฎ
โจ Xtensa Options โจ
These options are supported for Xtensa targets ๐ง
-mconst16,-mno-const16โ Enables or disables the use of"CONST16"instructions for loading constant values. The"CONST16"instruction is currently not a standard option from Tensilica. When enabled,"CONST16"instructions are always used in place of the standard"L32R"instructions. The use of"CONST16"is enabled by default only if the"L32R"instruction is not available ๐-mfused-madd,-mno-fused-maddโ Enables or disables the use of fused multiply/add and multiply/subtract instructions in the floating-point option. This has no effect if the floating-point option isn't also enabled. Disabling them forces the compiler to use separate instructions for the multiply and add/subtract operations. This may be desirable when strict IEEE 754-compliant results are required, since the fused multiply add/subtract instructions don't round the intermediate result, which produces results with more bits of precision than the IEEE standard specifies. Disabling fused multiply add/subtract instructions also ensures the program output isn't sensitive to the compiler's ability to combine multiply and add/subtract operations ๐งฎ-mserialize-volatile,-mno-serialize-volatileโ When enabled, GCC inserts"MEMW"instructions before"volatile"memory references to guarantee sequential consistency. The default is-mserialize-volatile. Use-mno-serialize-volatileto omit the"MEMW"instructions ๐-mforce-no-picโ For targets like GNU/Linux, where all user-mode Xtensa code must be position-independent code (PIC), this option disables PIC for compiling kernel code ๐ฃ-mtext-section-literals,-mno-text-section-literalsโ okay so these two control how literal pools get treated ๐ The default is-mno-text-section-literals, which tucks literals into their own separate section in the output file ๐ฆ That means the literal pool can live in data RAM/ROM, and the linker can merge literal pools from separate object files to kill redundant literals and improve code size โจ Flip it with-mtext-section-literalsand the literals get interspersed right in the text section, so they sit as close as possible to their references ๐ฆ This might be necessary for large assembly files ๐ With that flag on, the literals for each function go right before that function ๐-mauto-litpools,-mno-auto-litpoolsโ The default is-mno-auto-litpools, which puts literals in a separate section in the output file unless-mtext-section-literalsis used ๐ With-mauto-litpools, the assembler is the one that interleaves literals into the text section ๐ง The compiler doesn't produce explicit.literaldirectives and instead loads literals into registers withMOVIinstructions rather thanL32R, so the assembler can do relaxation and place literals wherever they're needed ๐ฅ This lets the assembler create several literal pools per function and assemble very big functions, which may not be possible with-mtext-section-literals๐-mtarget-align,-mno-target-alignโ When this is enabled, GCC tells the assembler to automatically align instructions to reduce branch penalties, at the cost of some code density ๐ซถ The assembler tries to widen density instructions to align branch targets and the instructions following call instructions ๐ฏ If there aren't enough preceding safe density instructions to align a target, no widening happens ๐ The default is-mtarget-align. These options don't affect auto-aligned instructions likeLOOP, which the assembler always aligns, either by widening density instructions or by insertingNOPinstructions ๐-mlongcalls,-mno-longcallsโ When this is enabled, GCC tells the assembler to translate direct calls into indirect calls, unless it can tell that the target of a direct call is in range of the call instruction ๐ญ This translation usually happens for calls to functions in other source files ๐ Specifically, the assembler turns a directCALLinto anL32Rfollowed by aCALLX๐ฆ The default is-mno-longcalls. Use this option in programs where the call target might be out of range ๐ธ It's implemented in the assembler, not the compiler, so the assembly code GCC generates still shows direct call instructions. Look at the disassembled object code to see the actual instructions ๐ Also, the assembler uses an indirect call for every cross-file call, not just the ones that really are out of range ๐
๐ธ zSeries Options ๐ธ
These are listed under ๐ง
โจ ENVIRONMENT โจ
okay bestie, this is the part where GCC lets you sneak in environment variables to tweak how it behaves ๐ Some of them point it at directories or prefixes to hunt for files, and others just set the overall vibe of the compilation ๐ธ
Quick heads up: you can also tell GCC where to search with options like -B, -I and -L. Those win over environment variables, and environment variables in turn win over whatever GCC's configuration says ๐
๐ LANG, LC_CTYPE, LC_MESSAGES, LC_ALL
These four are all about localization, so GCC can handle different national conventions ๐ GCC checks the LC_CTYPE and LC_MESSAGES locale categories if it's been configured to do so. You can set them to any value your installation supports. A typical one is en_GB.UTF-8, which is English from the UK encoded in UTF-8. It's giving British English ๐ฌ๐ง
LC_CTYPEโ this one handles character classification. GCC uses it to figure out where characters start and stop in a string. That matters for some multibyte encodings that have quote and escape characters which would otherwise be read as the end of a string or as an escape ๐ญLC_MESSAGESโ this sets the language used in diagnostic messages ๐ฌLC_ALLโ if this is set, it overrides bothLC_CTYPEandLC_MESSAGES. If it isn't, thenLC_CTYPEandLC_MESSAGESdefault to whateverLANGsays. If none of these are set at all, GCC falls back to traditional C English behavior ๐ง
๐ TMPDIR
If TMPDIR is set, it tells GCC which directory to use for temporary files ๐๏ธ GCC uses temp files to hold the output of one stage of compilation so the next stage can read it. For example, the output of the preprocessor is the input to the compiler proper ๐
๐ GCC_COMPARE_DEBUG
Setting GCC_COMPARE_DEBUG is nearly the same as passing -fcompare-debug to the compiler driver. Check that option's docs for the full tea โ
๐งญ GCC_EXEC_PREFIX
If GCC_EXEC_PREFIX is set, it gives a prefix to put in front of the names of the subprograms the compiler runs. No slash gets added when the prefix is joined with a subprogram name, so if you want one, end your prefix with a slash yourself ๐ฆ
If GCC_EXEC_PREFIX isn't set, GCC tries to work out a sensible prefix based on the pathname it was invoked with ๐ต๏ธโโ๏ธ If it can't find the subprogram using the prefix you gave, it checks the usual places instead.
The default value is prefix/lib/gcc/, where prefix is the prefix of the installed compiler. Most of the time that's whatever "prefix" was set to when you ran the configure script ๐ ๏ธ
Prefixes passed with -B beat this one. This prefix is also used to find linking files like crt0.o โจ
Now for the unusual part ๐ It also affects where GCC looks for header files. For each standard directory that normally starts with /usr/local/lib/gcc (more precisely, with the value of GCC_INCLUDE_DIR), GCC tries swapping that beginning out for your prefix to make an alternate directory name. So with -Bfoo/, GCC searches foo/bar just before it searches the standard /usr/local/lib/bar. If a standard directory starts with the configured prefix, the prefix gets replaced by GCC_EXEC_PREFIX when GCC looks for headers ๐
๐งบ COMPILER_PATH
The value of COMPILER_PATH is a colon-separated list of directories, very much like PATH ๐ง If GCC can't find subprograms using GCC_EXEC_PREFIX, it tries these directories when searching for subprograms.
๐ LIBRARY_PATH
The value of LIBRARY_PATH is also a colon-separated list of directories, like PATH ๐ When GCC is configured as a native compiler, it tries these directories when hunting for special linker files, if it can't find them with GCC_EXEC_PREFIX. Linking with GCC also searches these directories for ordinary libraries used with the -l option, but anything specified with -L comes first ๐ฅ
๐ถ LANG (multibyte characters)
This is the second LANG moment, and it's about passing locale info to the compiler ๐ฏ๐ต One thing it controls is which character set gets used when character literals, string literals and comments are parsed in C and C++. When the compiler is configured to allow multibyte characters, these values for LANG are recognized:
C-JISโ recognizes JIS characters.C-SJISโ recognizes SJIS characters.C-EUCJPโ recognizes EUCJP characters.
If LANG isn't defined, or it has some other value, the compiler uses mblen and mbtowc as defined by the default locale to recognize and translate multibyte characters ๐ธ
Some more environment variables affect the preprocessor ๐งโโ๏ธ
๐ CPATH, C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH
Each of these holds a list of directories to look for header files in, separated by a special character, much like PATH ๐ฆ That special character, PATH_SEPARATOR, depends on the target and gets decided when GCC is built. On Microsoft Windows-based targets it's a semicolon, and on almost every other target it's a colon.
CPATH works like -I, but its directories get searched after any paths given with -I on the command line. This one is used no matter which language is being preprocessed ๐
The other three only apply when preprocessing their particular language. Each one lists directories searched as if you'd used -isystem, but after any -isystem paths on the command line ๐ซถ
In all of these, an empty element tells the compiler to search its current working directory. Empty elements can show up at the start or end of a path. For example, if CPATH is ":/special/include", that's the same as -I. -I/special/include ๐
๐ DEPENDENCIES_OUTPUT
If this variable is set, its value says how to output dependencies for Make, based on the non-system header files the compiler processes. System header files get ignored in the dependency output ๐ซ
The value can be just a file name. In that case, the Make rules get written to that file, and the target name is guessed from the source file name. Or the value can look like file target, in which case the rules get written to file using target as the target name.
Basically, this variable is the same as combining -MM and -MF, with an optional -MT switch too ๐
๐งพ SUNPRO_DEPENDENCIES
This one is the same as DEPENDENCIES_OUTPUT, except system header files are not ignored. So it implies -M rather than -MM ๐ The dependence on the main input file is left out, though.
โฐ SOURCE_DATE_EPOCH
If this is set, its value is a UNIX timestamp that replaces the current date and time in the __DATE__ and __TIME__ macros. That way the embedded timestamps stay reproducible ๐โจ
The value has to be a UNIX timestamp, meaning the number of seconds (leap seconds excluded) since 01 Jan 1970 00:00:00, written in ASCII. It's the same as the output of date +%s on GNU/Linux and other systems that support the %s extension in date ๐งฎ
Pick a known timestamp, like the last modification time of the source or package, and let the build process set it ๐ ๏ธ
๐ BUGS
For instructions on reporting bugs, check out file:///usr/share/doc/gcc-10/README.Bugs ๐
๐ฆถ FOOTNOTES
- On some systems,
gcc -sharedneeds to build supplementary stub code for constructors to work. On multi-libbed systems,gcc -sharedmust select the correct support libraries to link against. Failing to supply the correct flags may lead to subtle defects. Supplying them in cases where they are not necessary is innocuous.
๐ SEE ALSO
gpl(7),gfdl(7),fsf-funding(7),cpp(1),gcov(1),as(1),ld(1),gdb(1),dbx(1)and the Info entries forgcc,cpp,as,ld,binutilsandgdb๐
๐ฉโ๐ป AUTHOR
See the Info entry for gcc, or http://gcc.gnu.org/onlinedocs/gcc/Contributors.html, for the legends who contributed to GCC ๐
โ๏ธ COPYRIGHT
Copyright (c) 1988-2020 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being "GNU General Public License" and "Funding Free Software", the Front-Cover texts being (a) (see below), and with the Back-Cover Texts being (b) (see below). A copy of the license is included in the gfdl(7) man page ๐
(a) The FSF's Front-Cover Text is:
A GNU Manual
(b) The FSF's Back-Cover Text is:
You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development.
That's the whole page, bestie! ๐๐ This one came from the gcc-10 build, dated 2023-07-07, and it's filed under GCC(1). Go compile something iconic ๐ฆโจ
๐ฆ where this page comes from
- ubuntu jammy: gcc-10-alpha-linux-gnu 10.5.0-1ubuntu1~22.04cross1
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms