[GHC] #15573: Make bindings with multiple occurrences a join point instead of duplicating code during inlining.

GHC ghc-devs at haskell.org
Mon Aug 27 23:24:03 UTC 2018


#15573: Make bindings with multiple occurrences a join point instead of duplicating
code during inlining.
-------------------------------------+-------------------------------------
           Reporter:  AndreasK       |             Owner:  (none)
               Type:  task           |            Status:  new
           Priority:  normal         |         Milestone:  8.6.1
          Component:  Compiler       |           Version:  8.4.3
           Keywords:  JoinPoints     |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 I have some intermediate core of the form:

 {{{
 -- RHS size: {terms: 9, types: 2, coercions: 0, joins: 0/0}
 cseAlts_s1dD [Occ=Once!T[1]] :: T -> Int#
 [LclId, CallArity=1, Str=<S,1*U>]
 cseAlts_s1dD
   = \ (lamVar_s1dw [Occ=Once!, Dmd=<S,1*U>, OS=OneShot] :: T) ->
       case lamVar_s1dw of wild_Xc [Dmd=<L,A>] {
         __DEFAULT -> 1#;
         B -> 2#;
         C -> 3#
       }

 -- RHS size: {terms: 14, types: 3, coercions: 0, joins: 0/0}
 $wfmerge_s1cZ [InlPrag=NOUSERINLINE[0]] :: T -> T -> Int#
 [LclId, Arity=2, CallArity=2, Str=<S,1*U><L,1*U>]
 $wfmerge_s1cZ
   = \ (w_s1cU [Occ=Once!, Dmd=<S,1*U>] :: T)
       (w_s1cV [Occ=Once*, Dmd=<L,1*U>] :: T) ->
       case w_s1cU of wild_XA [Dmd=<L,A>] {
         __DEFAULT -> -1#;
         A -> 2#;
         B -> cseAlts_s1dD w_s1cV;
         C -> cseAlts_s1dD w_s1cV
       }
 }}}

 Which after the simplifier ran got inlined into the branches to give us:

 {{{
 fmerge
   = \ (w_s1cU :: T) (w_s1cV :: T) ->
       case w_s1cU of {
         __DEFAULT -> GHC.Types.I# -1#;
         A -> GHC.Types.I# 2#;
         B ->
           case w_s1cV of {
             __DEFAULT -> GHC.Types.I# 1#;
             B -> GHC.Types.I# 2#;
             C -> GHC.Types.I# 3#
           };
         C ->
           case w_s1cV of {
             __DEFAULT -> GHC.Types.I# 1#;
             B -> GHC.Types.I# 2#;
             C -> GHC.Types.I# 3#
           }
       }
 }}}

 What I would really like GHC to do instead though is to make
 `cseAlts_s1dD` a join point when possible.
 This would eliminate both the call overhead AND the call duplication.

 The current behavior seems fine when we can't make it a join point. But
 when we can we should try to take advantage of that opportunity.

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


More information about the ghc-tickets mailing list