sheaf pushed to branch wip/andreask/ticked_joins at Glasgow Haskell Compiler / GHC

Commits:

8 changed files:

Changes:

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -672,7 +672,7 @@ lintRhs :: Id -> CoreExpr -> LintM (OutType, UsageEnv)
    672 672
     lintRhs bndr rhs
    
    673 673
         | JoinPoint arity <- idJoinPointHood bndr
    
    674 674
         = lintJoinLams arity (Just bndr) rhs
    
    675
    -    | AlwaysTailCalled arity <- tailCallInfo (idOccInfo bndr)
    
    675
    +    | AlwaysTailCalled arity _ <- tailCallInfo (idOccInfo bndr)
    
    676 676
         = lintJoinLams arity Nothing rhs
    
    677 677
     
    
    678 678
     -- Allow applications of the data constructor @StaticPtr@ at the top
    

  • compiler/GHC/Core/Opt/OccurAnal.hs
    ... ... @@ -2585,7 +2585,13 @@ But it is not necessary to gather CoVars from the types of other binders.
    2585 2585
     occAnal env (Tick tickish body)
    
    2586 2586
       = WUD usage' (Tick tickish body')
    
    2587 2587
       where
    
    2588
    -    WUD usage body' = occAnal env body
    
    2588
    +    WUD usage body' = occAnal env' body
    
    2589
    +
    
    2590
    +    env' = case tickish of
    
    2591
    +      -- Set that we are inside a profiling tick
    
    2592
    +      -- SLD TODO: explain why we need this info
    
    2593
    +      ProfNote {} -> setInProfTick env
    
    2594
    +      _           -> env
    
    2589 2595
     
    
    2590 2596
         usage'
    
    2591 2597
           | tickishCanScopeJoin tickish
    
    ... ... @@ -2809,6 +2815,13 @@ occAnalApp env (fun, args, ticks)
    2809 2815
         in WUD (markAllNonTail (fun_uds `andUDs` args_uds)) app_out
    
    2810 2816
     
    
    2811 2817
       where
    
    2818
    +    -- SLD TODO
    
    2819
    +    -- !_ = pprTrace "occAnalApp fallback: marking all non-tail"
    
    2820
    +    --        ( vcat [ text "fun:" <+> ppr fun
    
    2821
    +    --               , text "args:" <+> ppr args
    
    2822
    +    --               , text "ticks:" <+> ppr ticks
    
    2823
    +    --               ])
    
    2824
    +    --         ()
    
    2812 2825
         !(WUD args_uds app') = occAnalArgs env fun' args []
    
    2813 2826
         !(WUD fun_uds fun')  = occAnal (addAppCtxt env args) fun
    
    2814 2827
             -- The addAppCtxt is a bit cunning.  One iteration of the simplifier
    
    ... ... @@ -2929,6 +2942,7 @@ scrutinised y).
    2929 2942
     
    
    2930 2943
     data OccEnv
    
    2931 2944
       = OccEnv { occ_encl       :: !OccEncl      -- Enclosing context information
    
    2945
    +           , occ_prof_ticks :: !Int
    
    2932 2946
                , occ_one_shots  :: !OneShots     -- See Note [OneShots]
    
    2933 2947
                , occ_unf_act    :: Id -> Bool    -- Which Id unfoldings are active
    
    2934 2948
                , occ_rule_act   :: ActivationGhc -> Bool  -- Which rules are active
    
    ... ... @@ -2994,6 +3008,7 @@ type OneShots = [OneShotInfo]
    2994 3008
     initOccEnv :: OccEnv
    
    2995 3009
     initOccEnv
    
    2996 3010
       = OccEnv { occ_encl      = OccVanilla
    
    3011
    +           , occ_prof_ticks = 0
    
    2997 3012
                , occ_one_shots = []
    
    2998 3013
     
    
    2999 3014
                      -- To be conservative, we say that all
    
    ... ... @@ -3072,6 +3087,9 @@ setTailCtxt !env = env { occ_encl = OccVanilla }
    3072 3087
         -- Preserve occ_one_shots, occ_join points
    
    3073 3088
         -- Do not use OccRhs for the RHS of a join point (which is a tail ctxt):
    
    3074 3089
     
    
    3090
    +setInProfTick :: OccEnv -> OccEnv
    
    3091
    +setInProfTick !env = env { occ_prof_ticks = 1 + occ_prof_ticks env }
    
    3092
    +
    
    3075 3093
     mkRhsOccEnv :: OccEnv -> RecFlag -> OccEncl -> JoinPointHood -> Id -> CoreExpr -> OccEnv
    
    3076 3094
     -- See Note [The OccEnv for a right hand side]
    
    3077 3095
     -- For a join point:
    
    ... ... @@ -3813,7 +3831,7 @@ mkOneOcc !env id int_cxt arity
    3813 3831
       where
    
    3814 3832
         occ = OneOccL { lo_n_br = 1
    
    3815 3833
                       , lo_int_cxt = int_cxt
    
    3816
    -                  , lo_tail = AlwaysTailCalled arity }
    
    3834
    +                  , lo_tail = AlwaysTailCalled arity (occ_prof_ticks env) }
    
    3817 3835
     
    
    3818 3836
     -- Add several occurrences, assumed not to be tail calls
    
    3819 3837
     add_many_occ :: Var -> OccInfoEnv -> OccInfoEnv
    
    ... ... @@ -3866,13 +3884,20 @@ delBndrsFromUDs bndrs (UD { ud_env = env, ud_z_many = z_many
    3866 3884
            , ud_z_tail    = z_tail   `delVarEnvList` bndrs }
    
    3867 3885
     
    
    3868 3886
     markAllMany, markAllInsideLam, markAllNonTail, markAllManyNonTail
    
    3869
    -  :: UsageDetails -> UsageDetails
    
    3887
    +  :: HasDebugCallStack => UsageDetails -> UsageDetails
    
    3870 3888
     markAllMany      ud@(UD { ud_env = env }) = ud { ud_z_many   = env }
    
    3871 3889
     markAllInsideLam ud@(UD { ud_env = env }) = ud { ud_z_in_lam = env }
    
    3872
    -markAllNonTail   ud@(UD { ud_env = env }) = ud { ud_z_tail   = env }
    
    3873 3890
     markAllManyNonTail = markAllMany . markAllNonTail -- effectively sets to noOccInfo
    
    3874 3891
     
    
    3875
    -markAllInsideLamIf, markAllNonTailIf :: Bool -> UsageDetails -> UsageDetails
    
    3892
    +markAllNonTail ud@(UD { ud_env = env }) =
    
    3893
    +  if isNullUFM env
    
    3894
    +  then
    
    3895
    +    ud { ud_z_tail   = env }
    
    3896
    +  else
    
    3897
    +    -- SLD TODO pprTrace "markAllNonTail" ( text "zapping:" <+> ppr env $$ callStackDoc ) $
    
    3898
    +      ud { ud_z_tail   = env }
    
    3899
    +
    
    3900
    +markAllInsideLamIf, markAllNonTailIf :: HasDebugCallStack => Bool -> UsageDetails -> UsageDetails
    
    3876 3901
     
    
    3877 3902
     markAllInsideLamIf  True  ud = markAllInsideLam ud
    
    3878 3903
     markAllInsideLamIf  False ud = ud
    
    ... ... @@ -3969,7 +3994,7 @@ adjustNonRecRhs mb_join_arity (WTUD (TUD rhs_ja uds) rhs)
    3969 3994
       where
    
    3970 3995
         exact_join = mb_join_arity == JoinPoint rhs_ja
    
    3971 3996
     
    
    3972
    -adjustTailUsage :: Bool        -- True <=> Exactly-matching join point; don't do markNonTail
    
    3997
    +adjustTailUsage :: HasDebugCallStack => Bool        -- True <=> Exactly-matching join point; don't do markNonTail
    
    3973 3998
                     -> CoreExpr    -- Rhs usage, AFTER occAnalLamTail
    
    3974 3999
                     -> UsageDetails
    
    3975 4000
                     -> UsageDetails
    
    ... ... @@ -3981,7 +4006,7 @@ adjustTailUsage exact_join rhs uds
    3981 4006
       where
    
    3982 4007
         one_shot   = isOneShotFun rhs
    
    3983 4008
     
    
    3984
    -adjustTailArity :: JoinPointHood -> TailUsageDetails -> UsageDetails
    
    4009
    +adjustTailArity :: HasDebugCallStack => JoinPointHood -> TailUsageDetails -> UsageDetails
    
    3985 4010
     adjustTailArity mb_rhs_ja (TUD ja usage)
    
    3986 4011
       = markAllNonTailIf (mb_rhs_ja /= JoinPoint ja) usage
    
    3987 4012
     
    
    ... ... @@ -4015,7 +4040,7 @@ tagNonRecBinder :: TopLevelFlag -- At top level?
    4015 4040
     -- Precondition: OccInfo is not IAmDead
    
    4016 4041
     tagNonRecBinder lvl occ bndr
    
    4017 4042
       | okForJoinPoint lvl bndr tail_call_info
    
    4018
    -  , AlwaysTailCalled ar <- tail_call_info
    
    4043
    +  , AlwaysTailCalled ar _ <- tail_call_info
    
    4019 4044
       = (setBinderOcc occ bndr,        JoinPoint ar)
    
    4020 4045
       | otherwise
    
    4021 4046
       = (setBinderOcc zapped_occ bndr, NotJoinPoint)
    
    ... ... @@ -4102,7 +4127,7 @@ okForJoinPoint lvl bndr tail_call_info
    4102 4127
       = False
    
    4103 4128
       where
    
    4104 4129
         valid_join | NotTopLevel <- lvl
    
    4105
    -               , AlwaysTailCalled arity <- tail_call_info
    
    4130
    +               , AlwaysTailCalled arity _ <- tail_call_info
    
    4106 4131
     
    
    4107 4132
                    , -- Invariant 1 as applied to LHSes of rules
    
    4108 4133
                      all (ok_rule arity) (idCoreRules bndr)
    
    ... ... @@ -4120,8 +4145,8 @@ okForJoinPoint lvl bndr tail_call_info
    4120 4145
         lost_join | JoinPoint ja <- idJoinPointHood bndr
    
    4121 4146
                   = not valid_join ||
    
    4122 4147
                     (case tail_call_info of  -- Valid join but arity differs
    
    4123
    -                   AlwaysTailCalled ja' -> ja /= ja'
    
    4124
    -                   _                    -> False)
    
    4148
    +                   AlwaysTailCalled ja' _ -> ja /= ja'
    
    4149
    +                   _                      -> False)
    
    4125 4150
                   | otherwise = False
    
    4126 4151
     
    
    4127 4152
         ok_rule _ BuiltinRule{} = False -- only possible with plugin shenanigans
    
    ... ... @@ -4143,7 +4168,7 @@ okForJoinPoint lvl bndr tail_call_info
    4143 4168
                  , text "tc:" <+> ppr tail_call_info
    
    4144 4169
                  , text "rules:" <+> ppr (idCoreRules bndr)
    
    4145 4170
                  , case tail_call_info of
    
    4146
    -                 AlwaysTailCalled arity ->
    
    4171
    +                 AlwaysTailCalled arity _ ->
    
    4147 4172
                         vcat [ text "ok_unf:" <+> ppr (ok_unfolding arity (realIdUnfolding bndr))
    
    4148 4173
                              , text "ok_type:" <+> ppr (isValidJoinPointType arity (idType bndr)) ]
    
    4149 4174
                      _ -> empty ]
    
    ... ... @@ -4206,6 +4231,6 @@ orLocalOcc (OneOccL { lo_n_br = nbr1, lo_int_cxt = int_cxt1, lo_tail = tci1 })
    4206 4231
     orLocalOcc occ1 occ2 = andLocalOcc occ1 occ2
    
    4207 4232
     
    
    4208 4233
     andTailCallInfo :: TailCallInfo -> TailCallInfo -> TailCallInfo
    
    4209
    -andTailCallInfo info@(AlwaysTailCalled arity1) (AlwaysTailCalled arity2)
    
    4210
    -  | arity1 == arity2 = info
    
    4234
    +andTailCallInfo (AlwaysTailCalled arity1 p1) (AlwaysTailCalled arity2 p2)
    
    4235
    +  | arity1 == arity2 = AlwaysTailCalled arity1 (max p1 p2)
    
    4211 4236
     andTailCallInfo _ _  = NoTailCallInfo

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -201,6 +201,8 @@ data SimplEnv
    201 201
     
    
    202 202
           , seCaseDepth   :: !Int  -- Depth of multi-branch case alternatives
    
    203 203
     
    
    204
    +      , seProfTicks   :: !Int  -- SLD TODO
    
    205
    +
    
    204 206
           , seInlineDepth :: !Int  -- 0 initially, 1 when we inline an already-simplified
    
    205 207
                                    -- unfolding, and simplify again; and so on
    
    206 208
                                    -- See Note [Inline depth]
    
    ... ... @@ -588,6 +590,7 @@ mkSimplEnv mode fam_envs
    588 590
                  , seIdSubst     = emptyVarEnv
    
    589 591
                  , seRecIds      = emptyUnVarSet
    
    590 592
                  , seCaseDepth   = 0
    
    593
    +             , seProfTicks   = 0
    
    591 594
                  , seInlineDepth = 0 }
    
    592 595
             -- The top level "enclosing CC" is "SUBSUMED".
    
    593 596
     
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -39,7 +39,7 @@ import GHC.Core.Opt.Arity ( ArityType, exprArity, arityTypeBotSigs_maybe
    39 39
                               , pushCoTyArg, pushCoValArg, exprIsDeadEnd
    
    40 40
                               , typeArity, arityTypeArity, etaExpandAT )
    
    41 41
     import GHC.Core.SimpleOpt ( exprIsConApp_maybe, joinPointBinding_maybe, joinPointBindings_maybe )
    
    42
    -import GHC.Core.FVs     ( mkRuleInfo {- exprsFreeIds -} )
    
    42
    +import GHC.Core.FVs     ( mkRuleInfo )
    
    43 43
     import GHC.Core.Rules   ( lookupRule, getRules )
    
    44 44
     import GHC.Core.Multiplicity
    
    45 45
     
    
    ... ... @@ -57,10 +57,11 @@ import GHC.Types.Unique ( hasKey )
    57 57
     import GHC.Types.Basic
    
    58 58
     import GHC.Types.Tickish
    
    59 59
     import GHC.Types.Var    ( isTyCoVar )
    
    60
    +
    
    60 61
     import GHC.Builtin.Types.Prim( realWorldStatePrimTy )
    
    61 62
     import GHC.Builtin.Names( runRWKey, seqHashKey )
    
    62 63
     
    
    63
    -import GHC.Data.Maybe   ( isNothing, orElse, mapMaybe )
    
    64
    +import GHC.Data.Maybe   ( isNothing, orElse, fromMaybe, mapMaybe )
    
    64 65
     import GHC.Data.FastString
    
    65 66
     import GHC.Unit.Module ( moduleName )
    
    66 67
     import GHC.Utils.Outputable
    
    ... ... @@ -1442,7 +1443,10 @@ simplTick env tickish expr cont
    1442 1443
     
    
    1443 1444
       no_floating_past_tick =
    
    1444 1445
         do { let (inc,outc) = splitCont cont
    
    1445
    -       ; (floats, expr1) <- simplExprF env expr inc
    
    1446
    +             env' = case tickish of
    
    1447
    +                  ProfNote {} -> env { seProfTicks = seProfTicks env + 1 }
    
    1448
    +                  _ -> env
    
    1449
    +       ; (floats, expr1) <- simplExprF env' expr inc
    
    1446 1450
            ; let expr2    = wrapFloats floats expr1
    
    1447 1451
                  tickish' = simplTickish env tickish
    
    1448 1452
            ; rebuild env (mkTick tickish' expr2) outc
    
    ... ... @@ -2051,8 +2055,8 @@ simplNonRecJoinPoint :: SimplEnv -> InId -> InExpr
    2051 2055
                          -> InExpr -> SimplCont
    
    2052 2056
                          -> SimplM (SimplFloats, OutExpr)
    
    2053 2057
     simplNonRecJoinPoint env bndr rhs body cont
    
    2054
    -   = assert (isJoinId bndr ) $
    
    2055
    -     wrapJoinCont env cont $ \ env cont ->
    
    2058
    +   = assert (isJoinId bndr) $
    
    2059
    +     wrapJoinCont do_case_case env cont $ \ env cont ->
    
    2056 2060
          do { -- We push join_cont into the join RHS and the body;
    
    2057 2061
               -- and wrap wrap_cont around the whole thing
    
    2058 2062
             ; let mult   = contHoleScaling cont
    
    ... ... @@ -2062,14 +2066,19 @@ simplNonRecJoinPoint env bndr rhs body cont
    2062 2066
             ; (floats1, env3)  <- simplJoinBind NonRecursive cont (bndr,env) (bndr2,env2) (rhs,env)
    
    2063 2067
             ; (floats2, body') <- simplExprF env3 body cont
    
    2064 2068
             ; return (floats1 `addFloats` floats2, body') }
    
    2069
    +  where
    
    2070
    +    do_case_case
    
    2071
    +      | Just occMaxProfTicks <- occursUnderProfTick (idOccInfo bndr)
    
    2072
    +      , occMaxProfTicks > seProfTicks env
    
    2073
    +      = False
    
    2074
    +      | otherwise
    
    2075
    +      = seCaseCase env
    
    2065 2076
     
    
    2066
    -
    
    2067
    -------------------
    
    2068 2077
     simplRecJoinPoint :: SimplEnv -> [(InId, InExpr)]
    
    2069 2078
                       -> InExpr -> SimplCont
    
    2070 2079
                       -> SimplM (SimplFloats, OutExpr)
    
    2071 2080
     simplRecJoinPoint env pairs body cont
    
    2072
    -  = wrapJoinCont env cont $ \ env cont ->
    
    2081
    +  = wrapJoinCont do_case_case env cont $ \ env cont ->
    
    2073 2082
         do { let bndrs  = map fst pairs
    
    2074 2083
                  mult   = contHoleScaling cont
    
    2075 2084
                  res_ty = contResultType cont
    
    ... ... @@ -2079,30 +2088,38 @@ simplRecJoinPoint env pairs body cont
    2079 2088
            ; (floats1, env2)  <- simplRecBind env1 (BC_Join Recursive cont) pairs
    
    2080 2089
            ; (floats2, body') <- simplExprF env2 body cont
    
    2081 2090
            ; return (floats1 `addFloats` floats2, body') }
    
    2091
    +  where
    
    2092
    +    do_case_case
    
    2093
    +      | any ((seProfTicks env <) . fromMaybe 0 . occursUnderProfTick . idOccInfo . fst) pairs
    
    2094
    +      = False
    
    2095
    +      | otherwise
    
    2096
    +      = seCaseCase env
    
    2082 2097
     
    
    2083 2098
     --------------------
    
    2084
    -wrapJoinCont :: SimplEnv -> SimplCont
    
    2099
    +wrapJoinCont :: Bool
    
    2100
    +             -> SimplEnv -> SimplCont
    
    2085 2101
                  -> (SimplEnv -> SimplCont -> SimplM (SimplFloats, OutExpr))
    
    2086 2102
                  -> SimplM (SimplFloats, OutExpr)
    
    2087 2103
     -- Deal with making the continuation duplicable if necessary,
    
    2088 2104
     -- and with the no-case-of-case situation.
    
    2089
    -wrapJoinCont env cont thing_inside
    
    2105
    +wrapJoinCont do_case_case env cont thing_inside
    
    2090 2106
       | contIsStop cont        -- Common case; no need for fancy footwork
    
    2091 2107
       = thing_inside env cont
    
    2092 2108
     
    
    2093
    -  | not (seCaseCase env)
    
    2094
    -    -- See Note [Join points with -fno-case-of-case]
    
    2095
    -  = do { (floats1, expr1) <- thing_inside env (mkBoringStop (contHoleType cont))
    
    2096
    -       ; let (floats2, expr2) = wrapJoinFloatsX floats1 expr1
    
    2097
    -       ; (floats3, expr3) <- rebuild (env `setInScopeFromF` floats2) expr2 cont
    
    2098
    -       ; return (floats2 `addFloats` floats3, expr3) }
    
    2099
    -
    
    2100
    -  | otherwise
    
    2101
    -    -- Normal case; see Note [Join points and case-of-case]
    
    2109
    +  | do_case_case
    
    2110
    +    -- Normal situation: do the "case-of-case" transformation.
    
    2111
    +    -- See Note [Join points and case-of-case].
    
    2102 2112
       = do { (floats1, cont')  <- mkDupableCont env cont
    
    2103 2113
            ; (floats2, result) <- thing_inside (env `setInScopeFromF` floats1) cont'
    
    2104 2114
            ; return (floats1 `addFloats` floats2, result) }
    
    2105 2115
     
    
    2116
    +  | otherwise
    
    2117
    +    -- No "case-of-case" transformation.
    
    2118
    +    -- See Note [Join points with -fno-case-of-case].
    
    2119
    +  = do { (floats1, expr1) <- thing_inside env (mkBoringStop (contHoleType cont))
    
    2120
    +       ; let (floats2, expr2) = wrapJoinFloatsX floats1 expr1
    
    2121
    +       ; (floats3, expr3) <- rebuild (env `setInScopeFromF` floats2) expr2 cont
    
    2122
    +       ; return (floats2 `addFloats` floats3, expr3) }
    
    2106 2123
     
    
    2107 2124
     --------------------
    
    2108 2125
     trimJoinCont :: Id         -- Used only in error message
    
    ... ... @@ -2151,13 +2168,13 @@ evaluation context E):
    2151 2168
     
    
    2152 2169
     As is evident from the example, there are two components to this behavior:
    
    2153 2170
     
    
    2154
    -  1. When entering the RHS of a join point, copy the context inside.
    
    2155
    -  2. When a join point is invoked, discard the outer context.
    
    2171
    +  (wrapJoinCont) When entering the RHS of a join point, copy the context inside.
    
    2172
    +  (trimJoinCont) When a join point is invoked, discard the outer context.
    
    2156 2173
     
    
    2157 2174
     We need to be very careful here to remain consistent---neither part is
    
    2158 2175
     optional!
    
    2159 2176
     
    
    2160
    -We need do make the continuation E duplicable (since we are duplicating it)
    
    2177
    +We need to make the continuation E duplicable (since we are duplicating it)
    
    2161 2178
     with mkDupableCont.
    
    2162 2179
     
    
    2163 2180
     
    
    ... ... @@ -2184,7 +2201,8 @@ case-of-case we may then end up with this totally bogus result
    2184 2201
     This would be OK in the language of the paper, but not in GHC: j is no longer
    
    2185 2202
     a join point.  We can only do the "push continuation into the RHS of the
    
    2186 2203
     join point j" if we also push the continuation right down to the /jumps/ to
    
    2187
    -j, so that it can evaporate there.  If we are doing case-of-case, we'll get to
    
    2204
    +j, so that it can evaporate there (trimJoinCont). Then, if we are doing
    
    2205
    +case-of-case, we'll get to
    
    2188 2206
     
    
    2189 2207
         join x = case <j-rhs> of <outer-alts> in
    
    2190 2208
         case y of
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -1076,7 +1076,7 @@ joinPointBinding_maybe bndr rhs
    1076 1076
       | isJoinId bndr
    
    1077 1077
       = Just (bndr, rhs)
    
    1078 1078
     
    
    1079
    -  | AlwaysTailCalled join_arity <- tailCallInfo (idOccInfo bndr)
    
    1079
    +  | AlwaysTailCalled join_arity _ <- tailCallInfo (idOccInfo bndr)
    
    1080 1080
       , (bndrs, body) <- etaExpandToJoinPoint join_arity rhs
    
    1081 1081
       , let str_sig   = idDmdSig bndr
    
    1082 1082
             str_arity = count isId bndrs  -- Strictness demands are for Ids only
    

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -1977,7 +1977,7 @@ altsAreExhaustive (Alt con1 _ _ : alts)
    1977 1977
     -- Takes the function we are applying as argument.
    
    1978 1978
     etaExpansionTick :: Id -> GenTickish pass -> Bool
    
    1979 1979
     etaExpansionTick id t
    
    1980
    -  = hasNoBinding id &&
    
    1980
    +  = ( hasNoBinding id || isJoinId id ) && -- SLD TODO
    
    1981 1981
         ( tickishFloatable t || isProfTick t )
    
    1982 1982
     
    
    1983 1983
     {- Note [exprOkForSpeculation and type classes]
    

  • compiler/GHC/CoreToStg/Prep.hs
    ... ... @@ -1130,7 +1130,10 @@ cpeApp top_env expr
    1130 1130
                      hd = getIdFromTrivialExpr_maybe e2
    
    1131 1131
                      -- Determine number of required arguments. See Note [Ticks and mandatory eta expansion]
    
    1132 1132
                      min_arity = case hd of
    
    1133
    -                   Just v_hd -> if hasNoBinding v_hd then Just $! (idArity v_hd) else Nothing
    
    1133
    +                   Just v_hd ->
    
    1134
    +                    if hasNoBinding v_hd || isJoinId v_hd -- SLD TODO (re-use cantEtaReduceFun?)
    
    1135
    +                    then Just $! idArity v_hd
    
    1136
    +                    else Nothing
    
    1134 1137
                        Nothing -> Nothing
    
    1135 1138
               --  ; pprTraceM "cpe_app:stricts:" (ppr v <+> ppr args $$ ppr stricts $$ ppr (idCbvMarks_maybe v))
    
    1136 1139
                ; (app, floats, unsat_ticks) <- rebuild_app env args e2 emptyFloats stricts min_arity
    

  • compiler/GHC/Types/Basic.hs
    ... ... @@ -70,7 +70,7 @@ module GHC.Types.Basic (
    70 70
             BranchCount, oneBranch,
    
    71 71
             InterestingCxt(..),
    
    72 72
             TailCallInfo(..), tailCallInfo, zapOccTailCallInfo,
    
    73
    -        isAlwaysTailCalled,
    
    73
    +        isAlwaysTailCalled, occursUnderProfTick,
    
    74 74
     
    
    75 75
             EP(..),
    
    76 76
     
    
    ... ... @@ -1150,7 +1150,7 @@ instance Monoid InsideLam where
    1150 1150
     
    
    1151 1151
     -----------------
    
    1152 1152
     data TailCallInfo
    
    1153
    -  = AlwaysTailCalled {-# UNPACK #-} !JoinArity -- See Note [TailCallInfo]
    
    1153
    +  = AlwaysTailCalled {-# UNPACK #-} !JoinArity !Int-- See Note [TailCallInfo]
    
    1154 1154
       | NoTailCallInfo
    
    1155 1155
       deriving (Eq)
    
    1156 1156
     
    
    ... ... @@ -1167,9 +1167,15 @@ isAlwaysTailCalled occ
    1167 1167
       = case tailCallInfo occ of AlwaysTailCalled{} -> True
    
    1168 1168
                                  NoTailCallInfo     -> False
    
    1169 1169
     
    
    1170
    +occursUnderProfTick :: OccInfo -> Maybe Int
    
    1171
    +occursUnderProfTick occ =
    
    1172
    +  case tailCallInfo occ of
    
    1173
    +    AlwaysTailCalled _ b -> Just b
    
    1174
    +    NoTailCallInfo -> Nothing
    
    1175
    +
    
    1170 1176
     instance Outputable TailCallInfo where
    
    1171
    -  ppr (AlwaysTailCalled ar) = sep [ text "Tail", int ar ]
    
    1172
    -  ppr _                     = empty
    
    1177
    +  ppr (AlwaysTailCalled ar b) = sep [ text "Tail", brackets (int b), int ar ]
    
    1178
    +  ppr _                       = text "NoTailCallInfo" --empty
    
    1173 1179
     
    
    1174 1180
     -----------------
    
    1175 1181
     strongLoopBreaker, weakLoopBreaker :: OccInfo
    
    ... ... @@ -1217,7 +1223,8 @@ instance Outputable OccInfo where
    1217 1223
               pp_tail                = pprShortTailCallInfo tail_info
    
    1218 1224
     
    
    1219 1225
     pprShortTailCallInfo :: TailCallInfo -> SDoc
    
    1220
    -pprShortTailCallInfo (AlwaysTailCalled ar) = char 'T' <> brackets (int ar)
    
    1226
    +pprShortTailCallInfo (AlwaysTailCalled ar p)
    
    1227
    +  = char 'T' <> (brackets (text "P" <+> int p)) <> brackets (int ar)
    
    1221 1228
     pprShortTailCallInfo NoTailCallInfo        = empty
    
    1222 1229
     
    
    1223 1230
     {-