Hi all.

I provide a sample program which causes a strange behavior of strictness analyzer.
variant 1 {{{
module StrictUnusedArg (main) where
f2 :: Int -> Int -> Int
f2 x1 = if x1 == 0 then (\x0 -> x0) else let
    y = x1 - 1
    in f3 y y
f3 :: Int -> Int -> Int -> Int
f3 x2 = if x2 == 0 then f2 else let
    y = x2 - 1
    in f4 y y
f4 :: Int -> Int -> Int -> Int -> Int
f4 x3 = if x3 == 0 then f3 else let
    y = x3 - 1
    in \x2 x1 x0 -> f4 y x2 x1 (y + x0)
main = print (f2 100 0)
}}}
I expect that all arguments will be unboxed. "-ddump-simpl" reveals that actually types are
{{{
f2 :: Int# -> Int -> Int
f3 :: Int# -> Int -> Int -> Int
}}}
So when "f3" calls "f2" it unboxes the argument named "x1" and when "f2" calls "f3" it boxes the argument named "x1". "-ddump-stranal" knows strictness only for the "x2" of "f3" and "x1" of "f2".
{{{
f2:
[Arity 1
 Str: DmdType U(L)]
f3:
[Arity 1
 Str: DmdType U(L)]
}}}
I also can force the analyzer to think that "x1" and "x0" are strict by eta-expanding "f3":
variant 2 {{{
f3 x2 x1 x0 = if x2 == 0 then f2 x1 x0 else let
    y = x2 - 1
    in f4 y y x1 x0
}}}
"-ddump-stranal" yields:
{{{
f3:
[Arity 3
 Str: DmdType U(L)U(L)U(L)m]
f2:
[Arity 2
 Str: DmdType U(L)U(L)m]
}}}
I even do not use ($!).
So, the questions: Is it possible to change the strictness analyzer so it will treat "variant 1" as "variant 2"? Are these changes big?

Compiled with options:
$ ghc --make -fstrictness -fPIC -O3 -fforce-recomp blah-blah-blah
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.12.1

--
Best regards,
  Roman Beslik.

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to