
Claus Reinke wrote:
That was one of my questions in the optimization and rewrite rules thread: shouldn't -fvia-C be supported (as a non-default option) for at least as long as the alternative isn't a clear win in all cases?
The trouble with supporting multiple backends is that the cost in terms of testing and maintenance is high. And the registerised -fvia-C backend is particularly nasty, coming as it does with thousands of lines of Perl 4 that regularly get broken by new versions of gcc.
Yes, I can understand that you'd like to leave that part behind sometime before yesterday:-) I assume that this very complexity means that the -fvia-C route doesn't really get all the way to its most interesting promises (easy portability, and full backend optimizations inherited from gcc). And with that in mind, I can also understand that you don't want to put in any further work into trying to improve it, if that distracts from a better long-term solution. What I don't understand yet is the routemap for replacing -fvia-C. We've seen -fvia-C being demoted from default to backup (fine by me), we've seen a feature supported only by -fvia-C removed completely, instead of seeing support for it added to the -fasm route (macro-based APIs used to work with ffi, would now require a wrapper generator, which doesn't exist yet). Indications are that -fvia-C still tends to produce better code (even though it is not the best that ghc+gcc could produce) than -fasm (is that any better for the new backend?). And last, but not least, ghc has more limited resources than gcc, so how is ghc going to beat gcc at the portability and backend optimizations game while still making progress in its core competencies (ie, higher-level improvements; there's also the interesting side-issue of how the two stages of optimizations are going to interact in ghc, if there is a barrier that can only be crossed in one direction)?
Ok, thanks for bringing these points up. Hopefully I'll be able to lay your fears to rest: 1. Performance. -fvia-c currently produces code that is on average about 1% faster than -fasm: http://www.cse.unsw.edu.au/~dons/nobench/x86_64/results.html There's one notable exception: floating-point code on x86 (not x86_64) is terrible with -fasm, because our native code generator has a particularly simple/stupid implementation of the x87 instruction set. So we need to make the SSE2 code generator in the x86_64 backend work for x86, too. Having said that, the native backend has much more potential for generating faster code than we can with gcc. Firstly, it can re-use fixed registers (e.g. argument registers) within a basic block, whereas gcc can't. We don't do this currently because the C-- lacks the liveness information on jumps, but the new backend will be able to do it. I bet this alone will be worth more than that 1%. Secondly we have a much better handle on aliasing inside GHC than gcc does, and there's no good way to tell gcc what we know about aliasing. On x86, gcc has a grand total of 2 spare registers, which means it has virtually no scope for generating good code. There's also not much room for generating C that is more amenable to gcc's optimisations. The obvious thing to do is to make recursive functions look like loops. We've tried it (there's some experimental code in GHC to do it), IIRC it didn't buy very much. The lack of registers, and the lack of knowledge about aliasing (heap doesn't alias with stack) meant that gcc didn't do some obvious-looking optimisations. Trying to do better here is a dead end. 2. Portability. We haven't had a single new registerised port of GHC in many years now. While the via-C backend seems at first glance to offer some portability benefits, in practice porting the mangler is still a pain unless your platform is very similar to an existing one (e.g. vanilla ELF). The only C-only registerised port we had was Sparc, and thanks to Ben Lippmeier we now have a native backend for that too. Dropping the C backend won't harm any of our existing ports, and it doesn't seem like people are making new ports of GHC this way either. We'll still have the unregisterised porting route, whose only drawback is performance. Still, lots of platforms are successfully using unregisterised GHC ports (via Debian). One day maybe we'll have an LLVM backend, or similar. My impression is that right now we can't make an LLVM backend with as good performance as our native backend, without changes in LLVM. Maybe that will change. Nothing that we're doing now precludes adding an LLVM backend later, I believe. 3. Features. This is a non-issue: -fvia-C vs. -fasm should not affect what programs work. Up until 6.10.1 we had a bug whereby you could use -fvia-C to bind to CPP-based C APIs, but that bug was removed in 6.10.1. Ok, I realise that some people considered this to be a feature and its removal to be a regression. However, I believe it's more important that we conform to the FFI spec, and for -fasm to be consistent with -fvia-C. It's a slight inconvenience to have to write the wrappers, but in return you get more robust code. Of course we should have tool support to make generating the wrappers easier. Cheers, Simon