]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/doc/gccint/link-time-optimization/whole-program-assumptions-linker-plugin-and-symbol-visibilities.rst
sphinx: add missing trailing newline
[thirdparty/gcc.git] / gcc / doc / gccint / link-time-optimization / whole-program-assumptions-linker-plugin-and-symbol-visibilities.rst
CommitLineData
c63539ff
ML
1..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6.. _whopr:
7
8Whole program assumptions, linker plugin and symbol visibilities
9****************************************************************
10
11Link-time optimization gives relatively minor benefits when used
12alone. The problem is that propagation of inter-procedural
13information does not work well across functions and variables
14that are called or referenced by other compilation units (such as
15from a dynamically linked library). We say that such functions
16and variables are *externally visible*.
17
18To make the situation even more difficult, many applications
19organize themselves as a set of shared libraries, and the default
20ELF visibility rules allow one to overwrite any externally
21visible symbol with a different symbol at runtime. This
22basically disables any optimizations across such functions and
23variables, because the compiler cannot be sure that the function
24body it is seeing is the same function body that will be used at
25runtime. Any function or variable not declared ``static`` in
26the sources degrades the quality of inter-procedural
27optimization.
28
29To avoid this problem the compiler must assume that it sees the
30whole program when doing link-time optimization. Strictly
31speaking, the whole program is rarely visible even at link-time.
32Standard system libraries are usually linked dynamically or not
33provided with the link-time information. In GCC, the whole
34program option (:option:`-fwhole-program`) asserts that every
35function and variable defined in the current compilation
36unit is static, except for function ``main`` (note: at
37link time, the current unit is the union of all objects compiled
38with LTO). Since some functions and variables need to
39be referenced externally, for example by another DSO or from an
40assembler file, GCC also provides the function and variable
41attribute ``externally_visible`` which can be used to disable
42the effect of :option:`-fwhole-program` on a specific symbol.
43
44The whole program mode assumptions are slightly more complex in
45C++, where inline functions in headers are put into *COMDAT*
46sections. COMDAT function and variables can be defined by
47multiple object files and their bodies are unified at link-time
48and dynamic link-time. COMDAT functions are changed to local only
49when their address is not taken and thus un-sharing them with a
50library is not harmful. COMDAT variables always remain externally
51visible, however for readonly variables it is assumed that their
52initializers cannot be overwritten by a different value.
53
54GCC provides the function and variable attribute
55``visibility`` that can be used to specify the visibility of
56externally visible symbols (or alternatively an
57:option:`-fdefault-visibility` command line option). ELF defines
58the ``default``, ``protected``, ``hidden`` and
59``internal`` visibilities.
60
61The most commonly used is visibility is ``hidden``. It
62specifies that the symbol cannot be referenced from outside of
63the current shared library. Unfortunately, this information
64cannot be used directly by the link-time optimization in the
65compiler since the whole shared library also might contain
66non-LTO objects and those are not visible to the compiler.
67
68GCC solves this problem using linker plugins. A *linker
69plugin* is an interface to the linker that allows an external
70program to claim the ownership of a given object file. The linker
71then performs the linking procedure by querying the plugin about
72the symbol table of the claimed objects and once the linking
73decisions are complete, the plugin is allowed to provide the
74final object file before the actual linking is made. The linker
75plugin obtains the symbol resolution information which specifies
76which symbols provided by the claimed objects are bound from the
77rest of a binary being linked.
78
79GCC is designed to be independent of the rest of the toolchain
80and aims to support linkers without plugin support. For this
81reason it does not use the linker plugin by default. Instead,
82the object files are examined by :command:`collect2` before being
83passed to the linker and objects found to have LTO sections are
84passed to :command:`lto1` first. This mode does not work for
85library archives. The decision on what object files from the
86archive are needed depends on the actual linking and thus GCC
87would have to implement the linker itself. The resolution
88information is missing too and thus GCC needs to make an educated
89guess based on :option:`-fwhole-program`. Without the linker
90plugin GCC also assumes that symbols are declared ``hidden``
3ed1b4ce 91and not referred by non-LTO code by default.