Urk. Well spotted! I omitted a prime (writing env instead of env') in a late fix, and as a result practically no top-level rules and specialisations are being applied.
What an egregious bug. The good news is that a one-character fix should make 6.8.2 perform quite a bit better than 6.8.1! Simon | -----Original Message----- | From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of | kenny lu | Sent: 15 November 2007 06:49 | To: glasgow-haskell-users@haskell.org | Subject: GHC 6.8.1 SpecConstr | | Hi, | | Recall the example from Simon's paper appearing in ICFP 2007. | | myLast :: [a] -> a | myLast [] = error "" | myLast [x] = x | myLast (x:xs) = myLast xs | | which returns the last element in a list. | | Applying the idea in the paper, we should rewrite the function | as follows, | | myLast :: [a] -> a | myLast [] = error "" | myLast (x:xs) = myLast' x xs | where myLast' x [] = x | myLast' x (y:ys) = myLast' y ys | | which avoids redundant pattern tests. | | | We tried to compile the "unspecialized" version of myLast function | with GHC 6.8.1 | with -O2 -ddump-simpl flags and observe the core code as follows, | | ==================== Tidy Core ==================== | lvl_r72 :: forall a_a5P. a_a5P | [GlobalId] | [Str: DmdType b] | lvl_r72 = \ (@ a_a5P) -> GHC.Err.error @ a_a5P (GHC.Base.[] @ GHC.Base.Char) | | Rec { | Last.$smyLast :: forall a_a5P. a_a5P -> [a_a5P] -> a_a5P | [GlobalId] | [Arity 2] | Last.$smyLast = | \ (@ a_a5P) (ipv_s6i :: a_a5P) (ipv1_s6j :: [a_a5P]) -> | case ipv1_s6j of wild_X9 { | [] -> ipv_s6i; : ipv2_X6p ipv3_X6r -> Last.myLast @ a_a5P wild_X9 | } | Last.myLast :: forall a_a5B. [a_a5B] -> a_a5B | [GlobalId] | [Arity 1 | Str: DmdType S] | Last.myLast = | \ (@ a_a5P) (ds_d68 :: [a_a5P]) -> | case ds_d68 of wild_B1 { | [] -> lvl_r72 @ a_a5P; | : x_a5I ds1_d69 -> | case ds1_d69 of wild1_X9 { | [] -> x_a5I; : ipv_s6i ipv1_s6j -> Last.myLast @ a_a5P wild1_X9 | } | } | end Rec } | | | | | ==================== Tidy Core Rules ==================== | "SC:Last.myLast0" [0] | forall {@ a_a5P ipv_s6i :: a_a5P ipv1_s6j :: [a_a5P]} | Last.myLast @ a_a5P (GHC.Base.: @ a_a5P ipv_s6i ipv1_s6j) | = Last.$smyLast @ a_a5P ipv_s6i ipv1_s6j | | It seems that $smyLast is the specialized version of myLast | And the last tidy core rule says that we should replace the | application (myLast (x:xs)) | by ($smyLast x xs). | | We are surprised by the development of the second pattern of $smyLast. | In the second pattern, function myLast is applied to wild_X9 which is | the reference of | ipv_s6j. | | However, according to the running example, | it seems to make more sense if this application is | replaced by a recursive application ($smyLast ipv_3X6r) instead. | | Could you guys please enlighten me? | | Regards, | Kenny | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users