strictness of unused arguments

Roman Beslik beroal at ukr.net
Thu Mar 11 07:50:51 EST 2010


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.



More information about the Glasgow-haskell-users mailing list