Announcement

Collapse
No announcement yet.

GCC 12 Adds Support For Using The Mold Linker

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #11
    Is there a runtime performance difference or is it all buildtime?

    Comment


    • #12
      I'm having trouble building the kernel with gcc-12 from the ubuntu toolchains PPA.

      Code:
       CC /home/ph/kernel_main/build/linux-5.16-rc7/debian/build/build-generic/tools/objtool/check.o
      check.c: In function ‘validate_call’:
      check.c:2836:58: error: ‘%d’ directive output may be truncated writing between 1 and 10 bytes into a region of size 9 [-Werror=format-truncation=]
      2836 | snprintf(pvname, sizeof(pvname), "pv_ops[%d]", idx);
      | ^~
      In function ‘call_dest_name’,
      inlined from ‘call_dest_name’ at check.c:2824:27,
      inlined from ‘validate_call’ at check.c:2908:3:
      check.c:2836:50: note: directive argument in the range [-268435456, 268435455]
      2836 | snprintf(pvname, sizeof(pvname), "pv_ops[%d]", idx);
      If anyone knows how to fix, I'd appreciates.

      Comment


      • #13
        Originally posted by brad0 View Post

        No. GNU ld AKA the BFD linker AKA ld.bfd is different from the Gold linker AKA ld.gold. An operating system typically has an ld symlink to the linker (.e.g. ld.bfd, ld.gold, ld.lld. ld.mold, etc.)
        The /usr/bin/ld symlink chain on my Ubuntu PC:

        Screenshot_20211230_044415.png
        So, ld => x86_64-linux-gnu-ld => x86_64-linux-gnu-ld.bfd

        PS: is there any phoronix option to avoid the downsizing the uploaded image like this?
        Last edited by cl333r; 29 December 2021, 10:51 PM.

        Comment


        • #14
          Originally posted by cl333r View Post
          The /usr/bin/ld symlink chain on my Ubuntu PC:

          Screenshot_20211230_044415.png
          So, ld => x86_64-linux-gnu-ld => x86_64-linux-gnu-ld.bfd

          PS: is there any phoronix option to avoid the downsizing the uploaded image like this?
          Ya, the odd ball naming of the linker binary is because unlike lld the GNU linker only handles one arch at a time. So the naming is such so they'll co-exist and people might have other linkers for cross-compilation. There are a number of legacy design decisions with GCC and binutils regarding arch handling and cross-compilation that makes it ugly and a mess.

          Comment


          • #15
            Originally posted by kiffmet View Post
            Does the use of different linkers influence the performance of the resulting binary when not using LTO?
            Primarily the difference is link speed, which can matter a lot for CI functionality(*), and nearly nothing for the users of the resulting binary. There are, of course, edge cases where two linkers that happen to combine certain things in differnet orders may influence the performance on specific processor implementations, but those cases tend to be in the noise.

            (*) And for some projects, that is a lot of linking (every commit is built and tested across dozens of platforms), which can use lots of resources even before first release/deployment, and delay feedback to developers (and developers hate waiting for feedback, except for those wanting to slack off and do some chair sword play: https://xkcd.com/303/ )

            Comment


            • #16
              Here is a patch, which works for GCC 11, for those who want to use a stable GCC.
              Code:
              --- gcc/collect2.c
              +++ gcc/collect2.c
              @@ -776,6 +776,7 @@ main (int argc, char **argv)
                     USE_GOLD_LD,
                     USE_BFD_LD,
                     USE_LLD_LD,
              +      USE_MOLD_LD,
                     USE_LD_MAX
                   } selected_linker = USE_DEFAULT_LD;
                 static const char *const ld_suffixes[USE_LD_MAX] =
              @@ -784,7 +785,8 @@ main (int argc, char **argv)
                     PLUGIN_LD_SUFFIX,
                     "ld.gold",
                     "ld.bfd",
              -      "ld.lld"
              +      "ld.lld",
              +      "ld.mold"
                   };
                 static const char *const real_ld_suffix = "real-ld";
                 static const char *const collect_ld_suffix = "collect-ld";
              @@ -957,6 +959,8 @@ main (int argc, char **argv)
                     selected_linker = USE_GOLD_LD;
                   else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
                     selected_linker = USE_LLD_LD;
              +    else if (strcmp (argv[i], "-fuse-ld=mold") == 0)
              +      selected_linker = USE_MOLD_LD;
                  else if (strncmp (argv[i], "-o", 2) == 0)
                    {
                      /* Parse the output filename if it's given so that we can make
              @@ -1048,7 +1052,7 @@ main (int argc, char **argv)
                 ld_file_name = 0;
               #ifdef DEFAULT_LINKER
                 if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
              -      selected_linker == USE_LLD_LD)
              +      selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD)
                   {
                     char *linker_name;
               # ifdef HOST_EXECUTABLE_SUFFIX
              @@ -1283,7 +1287,7 @@ main (int argc, char **argv)
                         else if (!use_collect_ld
                              && startswith (arg, "-fuse-ld="))
                       {
              -          /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */
              +          /* Do not pass -fuse-ld={bfd|gold|lld|mold} to the linker. */
                         ld1--;
                         ld2--;
                       }
              --- gcc/common.opt
              +++ gcc/common.opt
              @@ -3046,6 +3046,10 @@ fuse-ld=lld
               Common Driver Negative(fuse-ld=lld)
               Use the lld LLVM linker instead of the default linker.
               
              +fuse-ld=mold
              +Common Driver Negative(fuse-ld=mold)
              +Use the Modern linker (MOLD) linker instead of the default linker.
              +
               fuse-linker-plugin
               Common Undocumented Var(flag_use_linker_plugin)
               
              
              --- gcc/gcc.c
              +++ gcc/gcc.c
              @@ -4282,6 +4282,10 @@ driver_handle_option (struct gcc_options *opts,
                      use_ld = ".gold";
                      break;
               
              +    case OPT_fuse_ld_mold:
              +       use_ld = ".mold";
              +       break;
              +
                   case OPT_fcompare_debug_second:
                     compare_debug_second = 1;
                     break;
              --- gcc/opts.c
              +++ gcc/opts.c
              @@ -3094,6 +3094,7 @@ common_handle_option (struct gcc_options *opts,
                   case OPT_fuse_ld_bfd:
                   case OPT_fuse_ld_gold:
                   case OPT_fuse_ld_lld:
              +    case OPT_fuse_ld_mold:
                   case OPT_fuse_linker_plugin:
                     /* No-op. Used by the driver and passed to us because it starts with f.*/
                     break;

              Comment


              • #17
                Originally posted by CommunityMember View Post

                Primarily the difference is link speed, which can matter a lot for CI functionality(*), and nearly nothing for the users of the resulting binary. There are, of course, edge cases where two linkers that happen to combine certain things in differnet orders may influence the performance on specific processor implementations, but those cases tend to be in the noise
                Fast linking for CI and development is extremely useful, but you still want the binary to be as optimized as possible. Linkers perform many optimizations, for example compressing dynamic relocations, relaxing relocations into simpler ones (eg. remove a GOT indirection). These optimizations can make significant improvements in binary size, load time and run time. Linkers also insert various veneers to extend branches that are out of range on many ISAs and even scan code for and workaround CPU bugs (I laugh when people bring up the "smart format, dumb linker" thing, that's so wrong...). So the question is whether this new linker supports all that, or whether it is fast by removing all these optimizations and features?

                Comment


                • #18
                  Originally posted by PerformanceExpert View Post
                  So the question is whether this new linker supports all that, or whether it is fast by removing all these optimizations and features?
                  From what I know about mold, it's mostly better parallelization

                  Comment


                  • #19
                    Originally posted by geearf View Post
                    Is there a runtime performance difference or is it all buildtime?
                    build time only

                    Comment


                    • #20
                      Originally posted by F.Ultra View Post

                      build time only
                      Thank you!

                      Comment

                      Working...
                      X