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