Next:Internal flags controllinglto1, Previous:Using summary information in IPA passes, Up:Link Time Optimization [Contents][Index]
Link-time optimization gives relatively minor benefits when usedalone. The problem is that propagation of inter-proceduralinformation does not work well across functions and variablesthat are called or referenced by other compilation units (such asfrom a dynamically linked library). We say that such functionsand variables areexternally visible.
To make the situation even more difficult, many applicationsorganize themselves as a set of shared libraries, and the defaultELF visibility rules allow one to overwrite any externallyvisible symbol with a different symbol at runtime. Thisbasically disables any optimizations across such functions andvariables, because the compiler cannot be sure that the functionbody it is seeing is the same function body that will be used atruntime. Any function or variable not declaredstatic inthe sources degrades the quality of inter-proceduraloptimization.
To avoid this problem the compiler must assume that it sees thewhole program when doing link-time optimization. Strictlyspeaking, the whole program is rarely visible even at link-time.Standard system libraries are usually linked dynamically or notprovided with the link-time information. In GCC, the wholeprogram option (-fwhole-program) asserts that everyfunction and variable defined in the current compilationunit is static, except for functionmain (note: atlink time, the current unit is the union of all objects compiledwith LTO). Since some functions and variables need tobe referenced externally, for example by another DSO or from anassembler file, GCC also provides the function and variableattributeexternally_visible which can be used to disablethe effect of-fwhole-program on a specific symbol.
The whole program mode assumptions are slightly more complex inC++, where inline functions in headers are put intoCOMDATsections. COMDAT function and variables can be defined bymultiple object files and their bodies are unified at link-timeand dynamic link-time. COMDAT functions are changed to local onlywhen their address is not taken and thus un-sharing them with alibrary is not harmful. COMDAT variables always remain externallyvisible, however for readonly variables it is assumed that theirinitializers cannot be overwritten by a different value.
GCC provides the function and variable attributevisibility that can be used to specify the visibility ofexternally visible symbols (or alternatively an-fdefault-visibility command line option). ELF definesthedefault,protected,hidden andinternal visibilities.
The most commonly used is visibility ishidden. Itspecifies that the symbol cannot be referenced from outside ofthe current shared library. Unfortunately, this informationcannot be used directly by the link-time optimization in thecompiler since the whole shared library also might containnon-LTO objects and those are not visible to the compiler.
GCC solves this problem using linker plugins. Alinkerplugin is an interface to the linker that allows an externalprogram to claim the ownership of a given object file. The linkerthen performs the linking procedure by querying the plugin aboutthe symbol table of the claimed objects and once the linkingdecisions are complete, the plugin is allowed to provide thefinal object file before the actual linking is made. The linkerplugin obtains the symbol resolution information which specifieswhich symbols provided by the claimed objects are bound from therest of a binary being linked.
GCC is designed to be independent of the rest of the toolchainand aims to support linkers without plugin support. For thisreason it does not use the linker plugin by default. Instead,the object files are examined bycollect2 before beingpassed to the linker and objects found to have LTO sections arepassed tolto1 first. This mode does not work forlibrary archives. The decision on what object files from thearchive are needed depends on the actual linking and thus GCCwould have to implement the linker itself. The resolutioninformation is missing too and thus GCC needs to make an educatedguess based on-fwhole-program. Without the linkerplugin GCC also assumes that symbols are declaredhiddenand not referred by non-LTO code by default.
Next:Internal flags controllinglto1, Previous:Using summary information in IPA passes, Up:Link Time Optimization [Contents][Index]