Inlining: unroll0.hs

File unroll0.hs, 1.6 KB (added by claus, 11 years ago)

trivial loop, INLINE loop PEEL 1 UNROLL 4, plus reassociation RULES

Line 
1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE CPP #-}
3{-# LANGUAGE MagicHash #-}
4module Main where
5import GHC.Prim
6
7-- ~1.1s  real DOINLINE+DOREASSOC
8-- ~1.65s real DOINLINE
9-- ~20.4s real without
10main = print $ loop 1 (10^9) body 0
11
12body :: Int -> Int -> Int
13body i acc = i+acc
14
15#ifdef DOINLINE
16-- simulating INLINE loop PEEL 1 UNROLL 4
17-- (assuming that PEEL 1 also triggers static argument transformation)
18{-# INLINE loop #-}
19loop :: Int -> Int -> (Int -> acc -> acc) -> acc -> acc
20loop !i !max !body !acc = loopW i acc
21  where
22  loopW !i !acc | i+4<=max  = loopW (i+4) (body (i+3) (body (i+2) (body (i+1) (body i acc))))
23  loopW !i !acc | i+3<=max  = loopW (i+3) (body (i+2) (body (i+1) (body i acc)))
24  loopW !i !acc | i+2<=max  = loopW (i+2) (body (i+1) (body i acc))
25  loopW !i !acc | i<=max    = loopW (i+1) (body i acc)
26                | otherwise = acc
27#else
28loop :: Int -> Int -> (Int -> acc -> acc) -> acc -> acc
29loop !i !max !body !acc | i<=max    = loop (i+1) max body (body i acc)
30                        | otherwise = acc
31#endif
32
33-- simulate reassociation of constants and variables into separate groups,
34-- to enable constant folding, replace repeated sums by multiplications
35-- (since we cannot distinguish variables and constants, we proceed by
36--  dead reconning, from our knowledge of what the code looks like..)
37#ifdef DOREASSOC
38{-# RULES
39"re-assoc" [~1] forall v x y z. (x+#y)+#(z+#v) = ((x+#y)+#z)+#v
40"collect1" [1]  forall x y.     (x+#y)+#x      = (2#*#x)+#y
41"collect2" [1]  forall n x y.   ((n*#x)+#y)+#x = ((n+#1#)*#x)+#y
42"collect3" [1]  forall n x y z. ((n*#x)+#y)+#z = (n*#x)+#(y+#z)
43  #-}
44#endif