#7109: Inlining depends on datatype size, even with INLINE pragmas
------------------------------+---------------------------------------------
 Reporter:  dreixel           |          Owner:                  
     Type:  bug               |         Status:  new             
 Priority:  normal            |      Component:  Compiler        
  Version:  7.5               |       Keywords:                  
       Os:  Unknown/Multiple  |   Architecture:  Unknown/Multiple
  Failure:  None/Unknown      |       Testcase:                  
Blockedby:                    |       Blocking:                  
  Related:                    |  
------------------------------+---------------------------------------------
 Consider the following code:
 {{{
 data Logic = T | F
            | Not Logic

 instance GEq Logic

 testEqLogic = geq (Not T) (Not F)
 }}}

 With a proper definitions of generic equality `geq` in class `GEq`, and an
 `instance Generic Logic`, we get the following core code with -O1:
 {{{
 Rec {
 Bug.$fGEqLogic_$cgeq [Occ=LoopBreaker]
   :: Bug.Logic -> Bug.Logic -> GHC.Types.Bool
 [GblId, Arity=2, Caf=NoCafRefs, Str=DmdType SS]
 Bug.$fGEqLogic_$cgeq =
   \ (x_ap1 :: Bug.Logic) (y_ap2 :: Bug.Logic) ->
     case x_ap1 of _ {
       Bug.T ->
         case y_ap2 of _ {
           Bug.T -> GHC.Types.True;
           Bug.F -> GHC.Types.False;
           Bug.Not g1_aBc_ayJ -> GHC.Types.False
         };
       Bug.F ->
         case y_ap2 of _ {
           Bug.T -> GHC.Types.False;
           Bug.F -> GHC.Types.True;
           Bug.Not g1_aBc_ayJ -> GHC.Types.False
         };
       Bug.Not g1_aBc_ayJ ->
         case y_ap2 of _ {
           __DEFAULT -> GHC.Types.False;
           Bug.Not g1_aBc1_XAu -> Bug.$fGEqLogic_$cgeq g1_aBc_ayJ
 g1_aBc1_XAu
         }
     }
 end Rec }
 }}}

 Nice and simple, looking just like what we would expect for an equality
 function for datatype `Logic`.

 Now we add one more constructor to datatype `Logic` (and adapt the
 `Generic` instance accordingly):
 {{{
 data Logic = T | F
            | Not Logic
            | And Logic Logic
 }}}

 GHC (HEAD) now generates 3000 lines of core code for the
 `Bug.$fGEqLogic_$cgeq` function, instead of something only slightly longer
 than above.

 Why is this? The second version of our `Logic` datatype is as easy to
 optimise as the first version; only the terms involved will be slightly
 longer. Attached file `Bug2.hs` is the input which gives the correct
 behaviour, while `Bug3.hs` is the input with one added constructor. (You
 might wonder if it has to do with the fact that the added constructor has
 more than one argument, but this is not the source of the problem.) Both
 files have `INLINE` pragmas pretty much everywhere (in fact, we're not
 `deriving Generic` so that we can put `INLINE` pragmas on `to` and
 `from`).

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7109>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

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

Reply via email to