Commit 4facbfd8 authored by jberryman's avatar jberryman

Rough LLVM/clang LTO WIP

`StgReturn` and `StgRun` defined with inline ASM are not making it into archive
built from `StgCRun.thr_o`, which is an LLVM bitcode LTO object.

(see commented .ll file)

After getting most of way through a build, did:

- used `llc` to compile `rts/dist/build/StgCRun.thr_o` and inspected assembly file
- copy-pasted code into textual IR (from `llvm-dis`) and removed wrapper function
   https://releases.llvm.org/6.0.0/docs/LangRef.html#moduleasm
- convert back into bitcode IR using `llvm-as rts/dist/build/StgCRun.thr_o.ll`
- re-run the `ar` command

It took a lot of other tweaking and trial and error to complete a build
though, so it's likely the state of repo here won't actually complete
successfully.

TODO for moar-LTO:
- bypass mangler with -fast-llvm (which for some reason seems not to
break things..?)
- shim `llc` to be a simple `cp`
- add flags to clang shim :  -O2 -mrelocation-model=static -msse -msse2

This will hopefully allow cross-module optimization of fllvm haskell,
e.g. more of our `libraries/*`
parent 41ec5884
#!/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+"$@"}
echo "$@" >> /tmp/hlint-lto-ar.out
# https://releases.llvm.org/6.0.0/docs/GoldPlugin.html#quickstart-for-using-lto-with-autotooled-projects
#exec /usr/lib/llvm-6.0/bin/llvm-ar ${1+"$@"}
# Try newer `ar` (doesn't seem to help undefined StgReturn when making libHSrts_thr.a)
# Not sure if version mismatch is a problem here, but older is incompatible with GNU ar:
exec /usr/lib/llvm-9/bin/llvm-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
# -fno-semantic-interposition is apparently default, but at least not recognized in clang-6
echo ${1+"$@"} >> /tmp/clang.out.hask
#exec /usr/lib/llvm-6.0/bin/clang -flto -gline-tables-only ${1+"$@"}
if [[ "$(pwd)" == *"/libffi"* ]]; then
exec gcc ${1+"$@"}
# Trying to ignore `-traditional` just results in errors
elif [[ "$@" == *"assembler-with-cpp"* || "$@" == *"-traditional"* ]]; then
exec gcc ${1+"$@"}
# DIDN'T HELP
# elif [[ "$@" == *"-shared"* ]]; then
# echo SHAAAAAARED >> /tmp/clang.out
# exec /usr/lib/llvm-6.0/bin/clang -gline-tables-only ${1+"$@"}
else
# This we used somewhat successfully to build ghc:
#/usr/lib/llvm-6.0/bin/clang -flto -gline-tables-only ${1+$(echo "$@" | sed "s/-x assembler /-x ir /g")} || /usr/lib/llvm-6.0/bin/clang -flto -gline-tables-only ${1+"$@"}
# This we're trying in conjunction with llc shim for building haskell projects:
# Copying some flags from `llc` invocation,
/usr/lib/llvm-6.0/bin/clang -flto -gline-tables-only -O2 -msse -msse2 ${1+$(echo "$@" | sed "s/-x assembler /-x ir /g")}
# -mllvm '-relocation-model=static'
# ^ doesn't work
fi
#!/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
# DISABLED FOR NOW SINCE WE GET ERRORS RIGHT AWAY
# Big hammer, make sure we use clang always; not sure if necessary.
exec clang ${1+"$@"}
#!/bin/bash
ld.lld ${1+"$@"}
lld
\ No newline at end of file
#!/bin/bash
/usr/lib/llvm-6.0/bin/ld.lld ${1+"$@"}
# (doesn't seem to help undefined StgReturn when making libHSrts_thr.a):
#/usr/lib/llvm-9/bin/ld.lld ${1+"$@"}
#!/bin/bash
# It seemed like there was some fuckery with 'lld' I had trouble working around with ./config opts
exec gold ${1+"$@"}
/usr/lib/llvm-6.0/bin/ld.lld ${1+"$@"}
# (doesn't seem to help undefined StgReturn when making libHSrts_thr.a):
#/usr/lib/llvm-9/bin/ld.lld ${1+"$@"}
#!/bin/bash
# https://releases.llvm.org/6.0.0/docs/GoldPlugin.html#quickstart-for-using-lto-with-autotooled-projects
exec /usr/lib/llvm-6.0/bin/llvm-nm ${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+"$@"}
# https://releases.llvm.org/6.0.0/docs/GoldPlugin.html#quickstart-for-using-lto-with-autotooled-projects
#exec /bin/true
exec /usr/lib/llvm-6.0/bin/llvm-ranlib ${1+"$@"}
......@@ -25,14 +25,12 @@
# define RTS_THUNK_INFO(i) extern const W_(i)[]
# define RTS_INFO(i) extern const W_(i)[]
# define RTS_CLOSURE(i) extern W_(i)[]
# define RTS_FUN_DECL(f) extern DLL_IMPORT_RTS StgFunPtr f(void)
#else
# define RTS_RET_INFO(i) extern DLL_IMPORT_RTS const StgRetInfoTable i
# define RTS_FUN_INFO(i) extern DLL_IMPORT_RTS const StgFunInfoTable i
# define RTS_THUNK_INFO(i) extern DLL_IMPORT_RTS const StgThunkInfoTable i
# define RTS_INFO(i) extern DLL_IMPORT_RTS const StgInfoTable i
# define RTS_CLOSURE(i) extern DLL_IMPORT_RTS StgClosure i
# define RTS_FUN_DECL(f) extern DLL_IMPORT_RTS StgFunPtr f(void)
#endif
#if defined(TABLES_NEXT_TO_CODE)
......@@ -46,6 +44,8 @@
# define RTS_FUN(f) RTS_FUN_INFO(f##_info); RTS_FUN_DECL(f##_entry)
# define RTS_THUNK(f) RTS_THUNK_INFO(f##_info); RTS_FUN_DECL(f##_entry)
#endif
// Again, trying to work around undefined reference issues
# define RTS_FUN_DECL(f) extern DLL_IMPORT_RTS StgFunPtr __attribute__((used)) f(void)
/* Stack frames */
RTS_RET(stg_upd_frame);
......
......@@ -8,10 +8,10 @@
# Uncomment one of these to select a build profile below:
# Full build with max optimisation and everything enabled (very slow build)
BuildFlavour = perf
#BuildFlavour = perf
# As above but build GHC using the LLVM backend
#BuildFlavour = perf-llvm
BuildFlavour = perf-llvm
# Perf build configured for a cross-compiler (using the LLVM backend)
#BuildFlavour = perf-cross
......
......@@ -365,6 +365,24 @@ stack unwinding.
*/
// ATTEMPT WORKAROUND: https://bugs.llvm.org/show_bug.cgi?id=28218
//
// else we get errors...
//
/* "inplace/bin/ghc-stage1" -o utils/iserv/stage2/build/tmp/ghc-iserv -hisuf hi -osuf o -hcsuf hc -static -O -H64m -fllvm -Wall -hide-all-packages -i -iutils/iserv/src -iutils/iserv/stage2/build -Iutils/iserv/stage2/build -iutils/iserv/stage2/build/iserv/autogen -Iutils/iserv/stage2/build/iserv/autogen -Iutils/iserv/. -Iutils/iserv/stage2/build/. -optP-include -optPutils/iserv/stage2/build/iserv/autogen/cabal_macros.h -package-id array-0.5.3.0 -package-id base-4.12.0.0 -package-id binary-0.8.6.0 -package-id bytestring-0.10.8.2 -package-id containers-0.6.0.1 -package-id deepseq-1.4.4.0 -package-id ghci-8.6.3 -package-id libiserv-8.6.3 -package-id unix-2.7.2.2 -no-hs-main -XHaskell2010 -threaded -optl-Wl,--export-dynamic -no-hs-main -no-user-package-db -rtsopts -Wnoncanonical-monad-instances -odir utils/iserv/stage2/build -hidir utils/iserv/stage2/build -stubdir utils/iserv/stage2/build -split-sections -static -O -H64m -fllvm -Wall -hide-all-packages -i -iutils/iserv/src -iutils/iserv/stage2/build -Iutils/iserv/stage2/build -iutils/iserv/stage2/build/iserv/autogen -Iutils/iserv/stage2/build/iserv/autogen -Iutils/iserv/. -Iutils/iserv/stage2/build/. -optP-include -optPutils/iserv/stage2/build/iserv/autogen/cabal_macros.h -package-id array-0.5.3.0 -package-id base-4.12.0.0 -package-id binary-0.8.6.0 -package-id bytestring-0.10.8.2 -package-id containers-0.6.0.1 -package-id deepseq-1.4.4.0 -package-id ghci-8.6.3 -package-id libiserv-8.6.3 -package-id unix-2.7.2.2 -no-hs-main -XHaskell2010 -threaded -optl-Wl,--export-dynamic -no-hs-main -no-user-package-db -rtsopts -Wnoncanonical-monad-instances utils/iserv/stage2/build/Main.o utils/iserv/stage2/build/cbits/iservmain.o */
/* Warning: -rtsopts and -with-rtsopts have no effect with -no-hs-main. */
/* Call hs_init_ghc() from your main() function to set these options. */
/* ld.lld: error: undefined symbol: StgReturn */
/* >>> referenced by ghc_8.s:29 */
/* >>> StgStartup.thr_o:(stg_stop_thread_info) in archive /home/me/Code/NOT_MY_CODE/ghc/rts/dist/build/libHSrts_thr.a */
static void dummmmmy(void) __attribute__((used));
static void dummmmmy(void) {
/* StgRunIsImplementedInAssembler(); */
StgRun(NULL, NULL);
StgReturn();
}
static void GNUC3_ATTRIBUTE(used)
StgRunIsImplementedInAssembler(void)
{
......
This diff is collapsed.
......@@ -511,11 +511,11 @@ rts/StgCRun_CC_OPTS += -w
#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
# TODO find which of these worked: ---------- disabling again for now
#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:
......
......@@ -689,6 +689,7 @@ getWanted verbose os tmpdir gccProgram gccFlags nmProgram mobjdumpProgram
oFile = tmpdir </> "tmp.o"
writeFile cFile cStuff
-- `nm` doesn't seem to work correctly on -flto -ffat-lto-objects :
-- UPDATE: ...nor with `clang` -flto...
-- https://stackoverflow.com/q/55126627/176841
execute verbose gccProgram (gccFlags ++ ["-fno-lto", "-c", cFile, "-o", oFile])
-- TODO DEBUGGING
......
......@@ -96,6 +96,13 @@ NEED_iserv_dyn = NO
endif
endif
# Bypass for failure due to undefined reference to StgRun/StgReturn
# in archive libHSrts_thr.a built from rts/dist/build/StgCRun.thr_o
# which is LLVM IR (from LTO)
NEED_iserv = NO
NEED_iserv_p = NO
NEED_iserv_dyn = NO
ifeq "$(NEED_iserv)" "YES"
$(eval $(call build-prog,utils/iserv,stage2,1))
endif
......
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