Ticket #7374 (new bug)

Opened 7 months ago

Last modified 6 months ago

rule not firing

Reported by: igloo Owned by:
Priority: normal Milestone: 7.8.1
Component: Compiler Version: 7.6.1
Keywords: Cc: kazu@…, carter.schonwald@…, duncan@…, pho@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

In the code below, the rule appears not to fire.

Based on the bytestring rules, reported as broken here:  http://www.haskell.org/pipermail/glasgow-haskell-users/2012-August/022775.html

ghc -O --make h.hs -ddump-simpl -fforce-recomp -Wall
module Q (f) where

{-# NOINLINE f #-}
f :: Bool -> String
f c = g ((==) c)

{-# NOINLINE g #-}
g :: (Bool -> Bool) -> String
g _ = "g"

h :: Bool -> String
h _ = "h"

{-# RULES "MyRule" forall x . g ((==) x) = h x #-}
==================== Tidy Core ====================
Result size of Tidy Core = {terms: 25, types: 21, coercions: 0}

lvl_rkK :: GHC.Types.Char
[GblId, Caf=NoCafRefs, Str=DmdType m]
lvl_rkK = GHC.Types.C# 'h'

lvl1_rkL :: [GHC.Types.Char]
[GblId, Caf=NoCafRefs, Str=DmdType]
lvl1_rkL =
  GHC.Types.:
    @ GHC.Types.Char lvl_rkK (GHC.Types.[] @ GHC.Types.Char)

h_reA :: GHC.Types.Bool -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType A]
h_reA = \ _ -> lvl1_rkL

lvl2_rkM :: GHC.Types.Char
[GblId, Caf=NoCafRefs, Str=DmdType m]
lvl2_rkM = GHC.Types.C# 'g'

lvl3_rkN :: [GHC.Types.Char]
[GblId, Caf=NoCafRefs, Str=DmdType]
lvl3_rkN =
  GHC.Types.:
    @ GHC.Types.Char lvl2_rkM (GHC.Types.[] @ GHC.Types.Char)

g_rez :: (GHC.Types.Bool -> GHC.Types.Bool) -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType A]
g_rez = \ _ -> lvl3_rkN

Q.f [InlPrag=NOINLINE] :: GHC.Types.Bool -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType A]
Q.f =
  \ (c_aeC :: GHC.Types.Bool) ->
    g_rez (GHC.Classes.$fEqBool_$c== c_aeC)

Change History

Changed 7 months ago by kazu-yamamoto

  • cc kazu@… added

Changed 7 months ago by carter

  • cc carter.schonwald@… added

Changed 7 months ago by simonpj

The rule doesn't fire for the usual reason: (==) lacks a NOINLINE [1] pragma (or suchlike) and as a result it inlines before the rule has a chance to fire.

This is a bit of a problem with all library-defined operations, where it hard to go back and add a NOINLINE pragma.

Would be be possible to use an intermediate function here, like this

(===) = (==)
{-# INLINE [1] (===) #-}

and now the rule can mention (===)?

Changed 7 months ago by igloo

  • cc duncan@… added

The ByteString? rules are:

{-# RULES
"ByteString specialise break (x==)" forall x.
    break ((==) x) = breakByte x
"ByteString specialise break (==x)" forall x.
    break (==x) = breakByte x
  #-}

I don't think your workaround would really help for the sort of use cases that I imagine the rule is intended to help with.

Changed 6 months ago by PHO

  • cc pho@… added
Note: See TracTickets for help on using tickets.