Commit 6f369534 authored by jberryman's avatar jberryman

Rough working LTO

Very rough and hacky, with some hacks unnecessary but which I haven't
taken the time to sort out yet.

you need to make sure you have the lto plugin set up correctly, e.g.:

  $ cd /usr/lib/bfd-plugins/
  $ sudo ln -s /usr/lib/gcc/x86_64-linux-gnu/6/liblto_plugin.so .

then do:

   $ export PATH=SHIMS_PATH:$PATH
   $ LD=gold  CC_STAGE0=gcc CC=gcc ./configure
   $ make

You should adjust your path in the same way when building with this GHC,
and you can do e.g.

  $ cabal new-build --disable-profiling --disable-library-profiling --with-compiler=your-ghc-source-tree/inplace/bin/ghc-stage2 --package-db=your-ghc-source-tree/inplace/lib/package.conf.d all

You can see `-time` log in gcc shim file, play with recompilation
options there.
parent ff9ee830
#!/bin/bash
# YOU DON'T NEED THIS (and it doesn't work)
# Also point to liblto_plugin.so directly (not sure if necessary; I thought we sorted this out...)
# https://stackoverflow.com/questions/46934111/which-is-the-correct-way-to-build-a-static-library-with-link-time-code-generatio/46935769
# I don't think --plugin is necessary now that we fixed symlink...
#exec /usr/bin/ar -T --plugin /usr/lib/gcc/x86_64-linux-gnu/6/liblto_plugin.so ${1+"$@"}
# https://stackoverflow.com/questions/24733986/gcc-lto-shared-library-am-i-right
export PATH=/usr/local/bin:/usr/bin:/bin
exec /usr/bin/gcc-ar ${1+"$@"}
#!/bin/bash
# Hack to strip DWARF debug, see
# https://bugzilla.redhat.com/show_bug.cgi?id=436374
# https://sourceware.org/bugzilla/show_bug.cgi?id=6428
exec /usr/bin/as ${1+$(echo "$@" | sed "s/--gdwarf2//g")}
#!/bin/bash
#
# - Try to silence LTO type error: -Wno-lto-type-mismatch
# - -fno-semantic-interposition , but see:
# $ ack HAS_VISIBILITY_HIDDEN -A4
# $ ack RTS_PRIVATE
# $ ack 'visibility.*default'
# It looks like these annotations are pretty sparse so maybe good idea!
# https://kristerw.blogspot.com/2016/11/inlining-shared-libraries-are-special.html
# https://stackoverflow.com/questions/35745543/new-option-in-gcc-5-3-fno-semantic-interposition
# - add (maybe pointless) -O2 -Wl,-O2 for link/compile in built binaries
# These should be unnecessary, at least in later gccs...
# - add -Wno-sync-nand
# See note in: libraries/ghc-prim/cbits/atomic.c
# - this seems to do nothing... nor -Wno-error ...
## NOTE! with -fno-fat-lto-objects (but with LTO) we erroneously get ".subsections_via_symbols... yes" in configure
exec /usr/bin/gcc -Wno-sync-nand -O2 -Wl,-O2 -grecord-gcc-switches -fno-semantic-interposition -Wno-lto-type-mismatch -flto -fno-fat-lto-objects -g1 -time=/tmp/gcc_lto_shim_build.nofat3.hello ${1+"$@"}
# NOTE: Use -ffat-lto-objects instead to (hopefully) create e.g. a bindist that
# will work normally if the user doesn't have a working gcc LTO setup
# We use nofat above so that things don't just quietly work when LTO is
# misconfigured/fubar
lld
\ No newline at end of file
#!/bin/bash
# It seemed like there was some fuckery with 'lld' I had trouble working around with ./config opts
exec gold ${1+"$@"}
#!/bin/bash
# I think this is probably unnecessary now that we set up the plugin symlink:
# https://stackoverflow.com/questions/25878407/how-can-i-use-lto-with-static-libraries
export PATH=/usr/local/bin:/usr/bin:/bin
exec /usr/bin/gcc-ranlib ${1+"$@"}
......@@ -170,6 +170,10 @@ hs_atomic_and64(StgWord x, StgWord64 val)
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wsync-fetch-and-nand-semantics-changed"
#elif defined(__GNUC__)
// At least when compiling with our LTO shim gcc this doesn't seem to do anything:
// a warning is raised (arbitrarily on the last occurrence of
// __sync_fetch_and_nand), marked "error", but build still completes
// successfully, whether this line is here or not:
#pragma GCC diagnostic ignored "-Wsync-nand"
#endif
......
# -----------------------------------------------------------------------------
# A Sample build.mk
#
# Uncomment one of the following BuildFlavour settings to get the desired
# overall build type.
# -------- Build profiles -----------------------------------------------------
# Uncomment one of these to select a build profile below:
# Full build with max optimisation and everything enabled (very slow build)
BuildFlavour = perf
# As above but build GHC using the LLVM backend
#BuildFlavour = perf-llvm
# Perf build configured for a cross-compiler (using the LLVM backend)
#BuildFlavour = perf-cross
# Perf build configured for a cross-compiler (using the NCG backend)
#BuildFlavour = perf-cross-ncg
# Fast build with optimised libraries, no profiling (RECOMMENDED):
#BuildFlavour = quick
# Fast build with optimised libraries, no profiling, with LLVM:
#BuildFlavour = quick-llvm
# Fast build configured for a cross compiler (using the LLVM backend)
#BuildFlavour = quick-cross
# Fast build configured for a cross compiler (using the NCG backend)
#BuildFlavour = quick-cross-ncg
# Even faster build. NOT RECOMMENDED: the libraries will be
# completely unoptimised, so any code built with this compiler
# (including stage2) will run very slowly, and many GHC tests
# will fail with this profile (see Trac #12141):
#BuildFlavour = quickest
# Profile the stage2 compiler:
#BuildFlavour = prof
# Profile the stage2 compiler (LLVM backend):
#BuildFlavour = prof-llvm
# A development build, working on the stage 1 compiler:
#BuildFlavour = devel1
# A development build, working on the stage 2 compiler:
#BuildFlavour = devel2
# A build with max optimisation that still builds the stage2 compiler
# quickly. Compiled code will be the same as with "perf". Programs
# will compile more slowly.
#BuildFlavour = bench
# As above but build GHC using the LLVM backend
#BuildFlavour = bench-llvm
# Bench build configured for a cross-compiler (using the LLVM backend)
#BuildFlavour = bench-cross
# Bench build configured for a cross-compiler (using the NCG backend)
#BuildFlavour = bench-cross-ncg
# Use the same settings as validate.
#BuildFlavour = validate
ifneq "$(BuildFlavour)" ""
include mk/flavours/$(BuildFlavour).mk
endif
# -------- Miscellaneous variables --------------------------------------------
# Set to V = 0 to get prettier build output.
# Please use V=1 (the default) when reporting GHC bugs.
#V=0
# Should all enabled warnings (see mk/warnings.mk) be turned into errors while
# building stage 2?
#WERROR=-Werror
# After stage 1 and the libraries have been built, you can uncomment this line:
#stage=2
# Then stage 1 will not be touched by the build system, until
# you comment the line again. This is a useful trick for when you're
# working on stage 2 and want to freeze stage 1 and the libraries for
# a while.
# Enable these if you would like DWARF debugging symbols for your libraries.
# This is necessary, for instance, to get DWARF stack traces out of programs
# built by the produced compiler. You must also pass --enable-dwarf-unwind to
# `configure` to enable the runtime system's builtin unwinding support.
#GhcLibHcOpts += -g3
#GhcRtsHcOpts += -g3
# Build the "extra" packages (see ./packages). This enables more tests. See:
# https://ghc.haskell.org/trac/ghc/wiki/Building/RunningTests/Running#AdditionalPackages
#BUILD_EXTRA_PKGS=YES
# Uncomment the following line to enable building DPH
#BUILD_DPH=YES
# Uncomment the following to force `integer-gmp` to use the in-tree GMP 6.1.2
# (other sometimes useful configure-options: `--with-gmp-{includes,libraries}`)
#libraries/integer-gmp_CONFIGURE_OPTS += --configure-option=--with-intree-gmp
# Enable pretty hyperlinked sources
#HADDOCK_DOCS = YES
#EXTRA_HADDOCK_OPTS += --quickjump --hyperlinked-source
# Don't strip debug and other unneeded symbols from libraries and executables.
STRIP_CMD = :
# TODO note: I can't remember if this was necessary:
#LD_STAGE0=gold # DOESN'T WORK
GccUseLdOpt="-fuse-ld=gold"
# rts/RtsSymbols.c:985:1: error:
# warning: type of ‘top_ct’ does not match original declaration [-Wlto-type-mismatch]
# RTS_SYMBOLS
# ^
# |
# 985 | RTS_SYMBOLS
# | ^
#
# THIS SEEMS TO DO NOTHING: TODO doublecheck
GhcRtsCcOpts="-Wno-lto-type-mismatch"
......@@ -28,6 +28,7 @@
#include "PosixSource.h"
#include "ghcconfig.h"
#include "boost/preprocessor/arithmetic/div.hpp"
#if defined(sparc_HOST_ARCH) || defined(USE_MINIINTERPRETER)
/* include Stg.h first because we want real machine regs in here: we
......@@ -465,6 +466,10 @@ StgRunIsImplementedInAssembler(void)
#if HAVE_SUBSECTIONS_VIA_SYMBOLS
// If we have deadstripping enabled and a label is detected as unused
// the code gets nop'd out.
// TODO this worked fine when we compiled -ffat-lto-objects (where configure sets HAVE_SUBSECTIONS_VIA_SYMBOLS=no)
// but when retrying without fat configure thinks we
// HAVE_SUBSECTIONS_VIA_SYMBOLS and we get an unknown pseudo-op
// error here (although line number was wrong...)
".no_dead_strip " xstr(STG_RUN_JMP) "\n"
#endif
xstr(STG_RUN_JMP) ":\n\t"
......
......@@ -501,6 +501,21 @@ rts/sm/Compact_CC_OPTS += -Wno-inline
# emits warnings about call-clobbered registers on x86_64
rts/StgCRun_CC_OPTS += -w
# else get "error: unable to emit symbol attribute in directive"
# llvm LTO:
# TODO does this work? Or LD_OPTS...??
#rts/StgCRun_HC_OPTS += -optc-fno-lto
#rts/StgCRun_HC_OPTS += -optl-fno-lto
# USELESS
#rts/StgCRun_CC_OPTS += -Wl,-fno-lto
#rts/StgCRun_CC_OPTS += -fno-lto
#rts/StgCRun_CC_OPTS += -g0
# How About for `gcc` LTO?:
# TODO find which of these worked:
rts/StgCRun_HC_OPTS += -optc-fno-lto
rts/StgCRun_HC_OPTS += -optl-fno-lto
rts/StgCRun_CC_OPTS += -Wl,-fno-lto
rts/StgCRun_CC_OPTS += -fno-lto
rts/RetainerProfile_CC_OPTS += -w
# On Windows:
......
......@@ -110,9 +110,30 @@ extern __thread gc_thread* gct;
here is that REG_Base is %ebx, but that is also used for -fPIC, so
it can't be stolen */
#elif defined(REG_Base) && !defined(i386_HOST_ARCH)
GCT_REG_DECL(gc_thread*, gct, REG_Base);
// GCT_REG_DECL(gc_thread*, gct, REG_Base);
// #define SET_GCT(to) gct = (to)
// #define DECLARE_GCT /* nothing */
/*
* Force __thread for now, with LTO, else we get
rts/sm/GCTDecl.h:113:1: error:
error: global register variable follows a function definition
GCT_REG_DECL(gc_thread*, gct, REG_Base);
^
|
113 | GCT_REG_DECL(gc_thread*, gct, REG_Base);
| ^
*
* ...like: https://github.com/InBetweenNames/gentooLTO/issues/135
*
* Some things to check out:
* https://lore.kernel.org/patchwork/patch/437199/
* https://gitlab.haskell.org/ghc/ghc/issues/7602
* https://stackoverflow.com/questions/27361194/global-register-variables-in-gcc
*/
extern __thread gc_thread* gct;
#define SET_GCT(to) gct = (to)
#define DECLARE_GCT /* nothing */
#define DECLARE_GCT __thread gc_thread* gct;
/* -------------------------------------------------------------------------- */
......
......@@ -688,7 +688,14 @@ getWanted verbose os tmpdir gccProgram gccFlags nmProgram mobjdumpProgram
cFile = tmpdir </> "tmp.c"
oFile = tmpdir </> "tmp.o"
writeFile cFile cStuff
execute verbose gccProgram (gccFlags ++ ["-c", cFile, "-o", oFile])
-- `nm` doesn't seem to work correctly on -flto -ffat-lto-objects :
-- https://stackoverflow.com/q/55126627/176841
execute verbose gccProgram (gccFlags ++ ["-fno-lto", "-c", cFile, "-o", oFile])
-- TODO DEBUGGING
print ("gcc call: ", gccFlags ++ ["-c", cFile, "-o", oFile])
_ <- readProcess "cp" [oFile, "/tmp/tmp.o"] ""
_ <- readProcess "cp" [cFile, "/tmp/tmp.c"] ""
xs <- case os of
"openbsd" -> readProcess objdumpProgam ["--syms", oFile] ""
"aix" -> readProcess objdumpProgam ["--syms", oFile] ""
......@@ -707,7 +714,7 @@ getWanted verbose os tmpdir gccProgram gccFlags nmProgram mobjdumpProgram
++ "Workaround: You may want to pass\n"
++ " --with-nm=$(xcrun --find nm-classic)\n"
++ "to 'configure'.\n"
Just x -> die ("unexpected value round-tripped for CONTROL_GROUP_CONST_291: " ++ show x)
Just x -> die ("unexpected value round-tripped for CONTROL_GROUP_CONST_291: " ++ show (x, ls))
rs <- mapM (lookupResult m) (wanteds os)
return rs
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment