#3755: Improve join point inlining
---------------------------------+------------------------------------------
    Reporter:  simonpj           |        Owner:                         
        Type:  task              |       Status:  new                    
    Priority:  normal            |    Milestone:  7.2.1                  
   Component:  Compiler          |      Version:  6.12.1                 
    Keywords:                    |     Testcase:                         
   Blockedby:                    |   Difficulty:                         
          Os:  Unknown/Multiple  |     Blocking:                         
Architecture:  Unknown/Multiple  |      Failure:  Runtime performance bug
---------------------------------+------------------------------------------

Comment(by reinerp):

 I just ran into this when playing around with view patterns, with a
 significantly smaller minimial example:


 {{{
 {-# LANGUAGE ViewPatterns #-}
 module Test1 where

 data D1 = A | B | C
 data D2 = A' | B' | C'

 conv A = A'
 conv B = B'
 conv C = C'

 foo :: (b -> D2) -> b -> a -> [a]
 foo f (f -> A') a =  [a]
 foo f (f -> B') a =  reverse [a]
 foo f (f -> C') a = reverse (reverse [a]) -- put some junk in the RHS to
 make it too big to inline
 {-# INLINE foo #-}

 h :: D1 -> a -> [a]
 h a b = foo conv a b

 -- "manually inlined" version
 j :: D1 -> a -> [a]
 j (conv -> A') a =  [a]
 j (conv -> B') a =  reverse [a]
 j (conv -> C') a = reverse (reverse [a])
 }}}
 With GHC on -O2, we get this core:

 {{{
 Test1.h =
   \ (@ a_ad5) (a_abW :: Test1.D1) (b_abX :: a_ad5) ->
     let {
       $w$j_sfk :: [a_ad5]
       [LclId, Str=DmdType]
       $w$j_sfk =
         case a_abW of _ {
           Test1.A -> Test1.h1 @ a_ad5;
           Test1.B ->
             GHC.List.reverse1
               @ a_ad5
               (GHC.Types.: @ a_ad5 b_abX (GHC.Types.[] @ a_ad5))
               (GHC.Types.[] @ a_ad5);
           Test1.C ->
             GHC.List.reverse1
               @ a_ad5
               (GHC.List.reverse1
                  @ a_ad5
                  (GHC.Types.: @ a_ad5 b_abX (GHC.Types.[] @ a_ad5))
                  (GHC.Types.[] @ a_ad5))
               (GHC.Types.[] @ a_ad5)
         } } in
     case a_abW of _ {
       Test1.A -> GHC.Types.: @ a_ad5 b_abX (GHC.Types.[] @ a_ad5);
       Test1.B -> $w$j_sfk;
       Test1.C -> $w$j_sfk
     }
 }}}
 Interestingly, the "manually inlined" function j has the core we want:

 {{{
 Test1.j =
   \ (@ a_ad7) (ds_ddP :: Test1.D1) (a_abY :: a_ad7) ->
     case ds_ddP of _ {
       Test1.A -> GHC.Types.: @ a_ad7 a_abY (GHC.Types.[] @ a_ad7);
       Test1.B ->
         GHC.List.reverse1
           @ a_ad7
           (GHC.Types.: @ a_ad7 a_abY (GHC.Types.[] @ a_ad7))
           (GHC.Types.[] @ a_ad7);
       Test1.C ->
         GHC.List.reverse1
           @ a_ad7
           (GHC.List.reverse1
              @ a_ad7
              (GHC.Types.: @ a_ad7 a_abY (GHC.Types.[] @ a_ad7))
              (GHC.Types.[] @ a_ad7))
           (GHC.Types.[] @ a_ad7)
     }
 }}}

 Reiner

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

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to