How does the LLVM backend compare performance-wise to the NGCs found in GHC?
Would it make sense to switch all backends to LLVM, so that GHC uses only LLVM for code generation like Rust does?
LLVM supports several architectures for which GHC has no NGC, these include MIPS, S390x, SPARC64 (although there is an out-of-tree NGC for SPARC64: https://github.com/jrtc27/ghc/commits/rebased), RISCV and some obscure targets.
Making the LLVM backend more prominent in GHC would make adding new targets easier, similar to the Rust compiler where adding a new architecture is relatively easy once LLVM supports it.
Thanks for the links, the discussion is very interesting.
I'm not against the NGC backends per se, but I think LLVM is a very nice alternative for those targets for which an NGC backend may never materialize due to lack of porters.
Would be great if MIPS, S390x and SPARC could get better and faster code generation support through LLVM for GHC.
There is even an LLVM backend for M68k being worked on and to be merged in the near future, so even the venerable 68000-based computers like the Amiga or Atari could get a fast GHC backend (currently we're using the unregisterised backend for these targets).
I'll have a look at what @schwab has contributed for RISC-V and see if there is a way I can get that to work for MIPS, S390x and SPARC (and eventually M68k) as well.
LLVM support is indeed much better than unregistered...
What's special about the RISC-V/LLVM target is that it's calling convention is written in C++, usually the LLVM code is generated from a template. So, for the general case AArch64 might be a better example.
Thanks, that looks useful. I'm not a Haskell expert by any means but my main job within Debian is to help with portability issues and having a faster GHC in Debian on MIPS, s390x, SPARC and m68k would help save a lot of CPU time.
I would even support such a development with a Bountysource campaign.
Looks like there already is a NCG for SPARC. According to @AndreasK 's blog post this should (in general) be faster in compiling than a LLVM solution - Maybe, that's exactly what you want for a packaging infrastructure?
I would happily volunteer for GHC/LLVM/MIPS, but we should first make sure that's what the GHC project needs/wants. (I found this commit where MIPS registered support was removed: 7b594a5d)
Darko Stefanovic wrote me asking about the status of this. Quoting my reply below:
Hi Darko,
I had indeed played around with using GHC's LLVM backend to target
RISC-V. The state of things is described in the tracking ticket [0].
At the time I was looking at this LLVM's own support for RISC-V
was quite immature (and not yet upstreamed); unsurprisingly, I quickly
ran into code generation bugs and put the project aside.
Since then LLVM's RISC-V support has improved considerably.
The missing piece for GHC support is support for the ghccc calling
convention. On most architectures this calling convention definition is
fairly trivial [1] since calling conventions are generally defined via
TableGen.
Unfortunately, this is not the case for the now-upstream RISC-V which
rather seems to define the majority of its calling convention logic in
its instruction lowering implementation [2]. It's possible that it
wouldn't be that hard to add ghccc support here but I've not looked
closely enough to know.
It would be great if someone could pick this project up (or even better,
implement a GHC native code generator backend for RISC-V, something that
might make for an interesting project for an interested student). I
would be happy to point an interested contributor in the right direction
to get started.
PS: I added this to the ticket because I think that's the core of the calling convention topic: How GHC maps it's registers and how these are mapped by LLVM.
I already started to wrap my head around the LLVM part and will pick it up as next task (if no-one else is faster ).
When it rains, it pours! It seems like we may now have two distinct efforts in this direction. @supersven is working in !4269 (closed) and @schwab is working on !4327 (closed). We should coordinate to ensure that we don't repeat work.
@supersven, @schwab: What are the statuses of your respective efforts?
My status is way not as far as @schwab 's: I ported the changes of @bgamari 's old branch to latest master (so you can configure risc-v as a target) and digged a bit into the LLVM/Calling Convention topic, but I've no finished branch. So, I would drop my approach in favour of @schwab 's.
I'd like to offer my help with the GHC-side code review and testing.
@schwab are you planning to write a Native Code Generator, too? Otherwise I would head over to this ...
I ran the testsuite while I was still debugging the llvm patch, to find small test cases to debug with. I'm going to rerun the testsuite with the latest patches.
Hello, great to see work being done on a (Linux) RISC-V support. I see riscv64 being mentioned couple of times but "riscv32" is nowhere to be found. Does "riscv" support implicitly means both "riscv32" and "riscv64" since @schwab's implementation uses the LLVM backend? If not, is a "riscv32" port made easier by this "riscv64" work?
Hello, great to see work being done on a (Linux) RISC-V support. I see riscv64 being mentioned couple of times but "riscv32" is nowhere to be found. Does "riscv" support implicitly means both "riscv32" and "riscv64" since @schwab's implementation uses the LLVM backend? If not, is a "riscv32" port made easier by this "riscv64" work?
RV64 support no doubts eases RV32 support. However, I am almost certain that further work will be necessary. @schwab, do you have a sense of what would be involved here?
Folks,
I'm trying to get excellent Andreas (@schwab ) work of registerised/llvm ghc working on Debian unstable. Debian provides GHC 8.8.4 as unregisterised compiler on riscv64 platform. First of all, I needed to bootstrap ghc 8.10.x. This is possible and to get unregisterised compiler quite easily if one apply @bgamari recommended patch from: #19965 (closed) and one also needs to workaround issue of not linking libatomic to rts libraries. Partial fix by Ben is in #18928 -- it's however incomplete for make based build. I'm preparing its updated version (for head) and hopefully submit shortly.
Andreas also warns that for building recent head with unregisterised compiler (e.g. unregisterised building registerised) one needs this patch: !4331 (diffs). -- this is to be applied to head if I understand that well.
So my status so far is: ghc 8.10.7 unregisterised built on debian and the compiler is able to built libraries well (e.g. -latomic is linked well). But when trying to build head using llvm-12 (provided by debian) and ghc 8.10.7 as a bootstrap compiler (and with Andreas recommended patch applies) I still get crashing ghc-stage2:
so this on on debian unstable. Now, I'm attempting to build head on Andreas reference openSUSE. I'm using this: https://en.opensuse.org/openSUSE:RISC-V in qemu 5.1.0. Will take hours/days till I know more and will report back about it here.
@trac-glaubitz have you tried this on some risc64 platform yourself? Would like to hear about your experience or needed tricks.