Loop unrolling + fusion ?

Simon Marlow marlowsd at gmail.com
Mon Mar 9 11:14:07 EDT 2009


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


More information about the Glasgow-haskell-users mailing list