Project

General

Profile

Actions

Feature #14421

closed

use GCC 10 as default primary compiler

Added by Andy Fiddaman over 1 year ago. Updated about 2 months ago.

Status:
Closed
Priority:
Low
Assignee:
-
Category:
tools - gate/build tools
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:
External Bug:

Description

This is an umbrella issue to track the work being done to support using the illumos gcc10 compiler as the primary compiler, replacing gcc7.


Related issues

Related to illumos gate - Bug #14255: gcc10 removes symbols from genunix, impeding CTF uniquificationClosedAndy Fiddaman

Actions
Related to illumos gate - Feature #14149: Use gcc10 as the shadow compilerClosedRobert Mustacchi

Actions
Related to illumos gate - Feature #14417: Disable gcc's reorder-blocks-and-partition optimisationClosedAndy Fiddaman

Actions
Related to illumos gate - Feature #14282: Warn when an inline function isn'tClosedAndy Fiddaman

Actions
Related to illumos gate - Bug #14422: gcc10 build does not remove unused static functionsClosed

Actions
Related to illumos gate - Feature #14749: gcc10 build should use -ftoplevel-reorderClosedAndy Fiddaman

Actions
Actions #1

Updated by Andy Fiddaman over 1 year ago

  • Related to Bug #14255: gcc10 removes symbols from genunix, impeding CTF uniquification added
Actions #2

Updated by Andy Fiddaman over 1 year ago

Actions #3

Updated by Andy Fiddaman over 1 year ago

  • Related to Feature #14417: Disable gcc's reorder-blocks-and-partition optimisation added
Actions #4

Updated by Andy Fiddaman over 1 year ago

Actions #5

Updated by Andy Fiddaman over 1 year ago

  • Description updated (diff)
Actions #6

Updated by Andy Fiddaman over 1 year ago

  • Related to Bug #14422: gcc10 build does not remove unused static functions added
Actions #7

Updated by Andy Fiddaman over 1 year ago

OmniOS bloody, as of 20220127, is now being built with gcc 10.
#14422 has also been pulled into that.

Actions #8

Updated by Andy Fiddaman 12 months ago

  • Related to Feature #14749: gcc10 build should use -ftoplevel-reorder added
Actions #9

Updated by Andy Fiddaman 3 months ago

The approach I took for testing gcc10 as a primary compiler was initially to compare the generated artefacts from gcc7 and gcc10, and then move on to a system booted with gcc10 bits and running various tests.

I began with some very broad checks - comparing the sizes of the .SUNW_ctf sections, and comparing which functions were present in each object, and their sizes, and then working to understand the differences.

With CTF, it quickly became apparent that there was a significant difference in the kernel. In particular, there was a lot less CTF data in genunix and more in the other kernel modules. The reason for this is that gc10 defaults eliminate-unused-debug-symbols to on. This means that, when using gcc10 as the primary compiler, symbols are stripped from the genunix object, leaving less there for the subsequent CTF uniquification step. As a result, symbols which are used by several modules end up being duplicated in each module instead of held once within genunix.

This was addressed as #14255 by adding -fno-eliminate-unused-debug-symbols and -fno-eliminate-unused-debug-types for the genunix build to support continued module uniquification. This is not done for the other objects, and results in a general reduction in the CTF section size across the board, with unused objects being removed. As an example, the __FILE struct is in pretty much every object with gcc7, and only in those that use it with gcc10.

Next, looking at functions that had changed size significantly led to discovering that gcc10 uses different thresholds in its heuristics for inlining functions; several functions marked explicitly with inline were not being inlined. The was also the case for some with gcc7, but gcc10 was inlining even fewer.
I went through and cleaned up the few functions that can never be inlined for various reasons, enabled the compiler's warning option that will report when a function is not inlined, and explicitly specified the function size limit to get more consistent behaviour between the gcc versions. The warning part was only applied to usr/src/uts as the userland components pull in unbundled libraries (such as openssl) which triggered them. This change means that if you mark a function in the kernel as inline but the compiler chooses not to inline it, then it's a fatal error unless you override that in the respective Makefile (this has been in gate for a year now). The key part of this change in relation to gcc10 was explicitly specifying the inline thresholds, as they were significantly different between gcc7 and 10.
#14282

Comparing the functions/symbols in each generated artefact showed that gcc10 was adding additional .cold symbols, such as kmem_error.cold. This was addressed by enabling the -_gcc=-fno-reorder-blocks-and-partition option. This was done for both gcc7 and gcc10 and eliminated these extra symbols from being generated.
#14417

A final noted difference is that gcc10 is no longer removing unused static functions from objects, which results in bonus unecessary functions being left in artefacts. I did some specific cleanup in #14422 to reduce this, mostly by moving functions properly to within DEBUG and SPARC guards so they don't appear in the output but there are still some extra functions in the gcc10 artefacts.
I experimented with different compiler options and found that enabling -ftoplevel-reorder caused these functions to be removed. However, it also, as you might expect, re-orders functions, and also employs constant folding on static global variables which are only read. This effectively removes a lot of historic tuneables. Anything intended to be a tuneable should not, of course, be static, but many of the things affected here seem to be superficially useful (nfs4_max_threads for example). They are enumerated in the following issue. In the end, -ftoplevel-reorder was not applied and there are 297 additional functions in the non-DEBUG gcc10 build artefacts (fewer with DEBUG as many of these are functions used only in DEBUG builds).
#14749

Having got the gcc10 output closer to gcc7, I moved onto broader testing. The various test suites were run with matching output, the list of fbt probes was compared between the builds - there were new functions as described above, but nothing has been lost. Spot checks were performed on the fbt probe location in functions to ensure they are placed before any branches. These are basically the checks recommended in IPD7.

OmniOS has shipped the last two stable releases with a gcc10 primary and only one regression has been found in that time - #14948 - which increases confidence.

Actions #10

Updated by Electric Monk 3 months ago

  • Gerrit CR set to 2676
Actions #11

Updated by Electric Monk about 2 months ago

  • Status changed from In Progress to Closed
  • % Done changed from 0 to 100

git commit 69cb22ea4d30fbf14fe34fe9fa04d9c292fa7af4

commit  69cb22ea4d30fbf14fe34fe9fa04d9c292fa7af4
Author: Andy Fiddaman <illumos@fiddaman.net>
Date:   2023-04-12T23:16:07.000Z

    14421 use GCC 10 as default primary compiler
    Reviewed by: Robert Mustacchi <rm+illumos@fingolfin.org>
    Reviewed by: Dan McDonald <danmcd@mnx.io>
    Approved by: Gordon Ross <gordon.w.ross@gmail.com>

Actions

Also available in: Atom PDF