Opened 7 years ago

Last modified 4 years ago

#7374 new bug

rule not firing

Reported by: igloo Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.6.1
Keywords: Cc: kazu@…, carter.schonwald@…, duncan@…, pho@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime performance bug Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

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 (11)

comment:1 Changed 7 years ago by kazu-yamamoto

Cc: kazu@… added

comment:2 Changed 7 years ago by carter

Cc: carter.schonwald@… added

comment:3 Changed 7 years 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 (===)?

comment:4 Changed 7 years 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.

comment:5 Changed 7 years ago by PHO

Cc: pho@… added

comment:6 Changed 6 years ago by nomeata

Looking at these many reports about rules not firing (e.g. #7398) due to other stuff happening earlier I wonder: Can’t we have a round of applying rules very early, before any inlining?

comment:7 Changed 5 years ago by thoughtpolice

Milestone: 7.8.37.10.1

Moving to 7.10.1

comment:8 Changed 5 years ago by thoughtpolice

Milestone: 7.10.17.12.1

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

comment:9 Changed 4 years ago by thomie

Type of failure: None/UnknownRuntime performance bug

comment:10 Changed 4 years ago by thoughtpolice

Milestone: 7.12.18.0.1

Milestone renamed

comment:11 Changed 4 years ago by thomie

Milestone: 8.0.1
Note: See TracTickets for help on using tickets.