[Haskell-cafe] GHC optimisations

Philip Armstrong phil at kantaka.co.uk
Tue Aug 21 07:22:14 EDT 2007


On Mon, Aug 20, 2007 at 09:57:38PM +0100, Simon Peyton-Jones wrote:
>GHC does some constant folding, but little by way of strength
>reduction, or using shifts instead of multiplication.  It's pretty
>easy to add more: it's all done in a single module.  Look at
>primOpRules in the module PrelRules.
>
>Patches welcome!  But please also supply test-suite tests that check
> the correctness of the rules.

Sucking another example out of comp.lang.functional:

This:

   import System

   f :: Int -> Int -> Int
   f s n = if n > 0 then f (s+n) (n-1) else s

   main = do
         [n] <- getArgs
         putStrLn $ show $ f 0 (read n) 

is 3-4x slower than this:

   #include <stdio.h>
   #include <stdlib.h>
   #include <assert.h>

   int f(int s, int n) { 
     return n > 0 ? f(s+n, n-1) : s;
   }

   int main(int argc, char *argv[]) { 
     assert(argc == 2);
     printf("%d\n", f(0, strtol(argv[1],0,0)));
   }

The generated assembler suggests (if I've read it correctly) that gcc
is spotting that it can replace the tail call with a jump in the C
version, but for some reason it can't spot it for the Haskell version
when compiling with -fvia-C (and neither does ghc itself using
-fasm). So the haskell version ends up pushing and popping values on
and off the stack for every call to f, which is a bit sad.

Phil

-- 
http://www.kantaka.co.uk/ .oOo. public key: http://www.kantaka.co.uk/gpg.txt


More information about the Haskell-Cafe mailing list