sheaf pushed to branch wip/debug-join-point at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -56,6 +56,7 @@ import GHC.Prelude
    56 56
     
    
    57 57
     import GHC.Core.Coercion.Opt ( OptCoercionOpts )
    
    58 58
     import GHC.Core.FamInstEnv ( FamInstEnv )
    
    59
    +import GHC.Core.SimpleOpt ( isJoinPointBinding )
    
    59 60
     import GHC.Core.Opt.Arity ( ArityOpts(..) )
    
    60 61
     import GHC.Core.Opt.Simplify.Monad
    
    61 62
     import GHC.Core.Rules.Config ( RuleOpts(..) )
    
    ... ... @@ -854,7 +855,7 @@ isEmptyJoinFloats = isNilOL
    854 855
     
    
    855 856
     unitLetFloat :: OutBind -> LetFloats
    
    856 857
     -- This key function constructs a singleton float with the right form
    
    857
    -unitLetFloat bind = assert (all (not . isJoinId) (bindersOf bind)) $
    
    858
    +unitLetFloat bind = assert (all (not . isJoinPointBinding) (bindersOf bind)) $
    
    858 859
                         LetFloats (unitOL bind) (flag bind)
    
    859 860
       where
    
    860 861
         flag (Rec {})                = FltLifted
    
    ... ... @@ -867,7 +868,7 @@ unitLetFloat bind = assert (all (not . isJoinId) (bindersOf bind)) $
    867 868
           | otherwise                = FltCareful
    
    868 869
     
    
    869 870
     unitJoinFloat :: OutBind -> JoinFloats
    
    870
    -unitJoinFloat bind = assert (all isJoinId (bindersOf bind)) $
    
    871
    +unitJoinFloat bind = assert (all isJoinPointBinding (bindersOf bind)) $
    
    871 872
                          unitOL bind
    
    872 873
     
    
    873 874
     mkFloatBind :: SimplEnv -> OutBind -> (SimplFloats, SimplEnv)
    
    ... ... @@ -1123,7 +1124,7 @@ simplRecBndrs :: SimplEnv -> [InBndr] -> SimplM SimplEnv
    1123 1124
     -- Recursive let binders
    
    1124 1125
     simplRecBndrs env@(SimplEnv {}) ids
    
    1125 1126
       -- See Note [Bangs in the Simplifier]
    
    1126
    -  = assert (all (not . isJoinId) ids) $
    
    1127
    +  = assert (all (not . isJoinPointBinding) ids) $
    
    1127 1128
         do  { let (!env1, ids1) = mapAccumL substIdBndr env ids
    
    1128 1129
             ; seqIds ids1 `seq` return env1 }
    
    1129 1130
     
    
    ... ... @@ -1256,7 +1257,7 @@ simplRecJoinBndrs :: SimplEnv -> [InBndr]
    1256 1257
     -- context being pushed inward may change types
    
    1257 1258
     -- See Note [Return type for join points]
    
    1258 1259
     simplRecJoinBndrs env@(SimplEnv {}) ids mult res_ty
    
    1259
    -  = assert (all isJoinId ids) $
    
    1260
    +  = assert (all isJoinPointBinding ids) $
    
    1260 1261
         do  { let (env1, ids1) = mapAccumL (simplJoinBndr mult res_ty) env ids
    
    1261 1262
             ; seqIds ids1 `seq` return env1 }
    
    1262 1263
     
    
    ... ... @@ -1283,7 +1284,7 @@ adjustJoinPointType :: Mult
    1283 1284
     -- INVARIANT: If any of the first n binders are foralls, those tyvars
    
    1284 1285
     -- cannot appear in the original result type. See isValidJoinPointType.
    
    1285 1286
     adjustJoinPointType mult new_res_ty join_id
    
    1286
    -  = assert (isJoinId join_id) $
    
    1287
    +  = assert (isJoinPointBinding join_id) $
    
    1287 1288
         setIdType join_id new_join_ty
    
    1288 1289
       where
    
    1289 1290
         join_arity = idJoinArity join_id
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -38,7 +38,7 @@ import GHC.Core.Utils
    38 38
     import GHC.Core.Opt.Arity ( ArityType, exprArity, arityTypeBotSigs_maybe
    
    39 39
                               , pushCoTyArg, pushCoValArg, exprIsDeadEnd
    
    40 40
                               , typeArity, arityTypeArity, etaExpandAT )
    
    41
    -import GHC.Core.SimpleOpt ( exprIsConApp_maybe, joinPointBinding_maybe, joinPointBindings_maybe )
    
    41
    +import GHC.Core.SimpleOpt ( exprIsConApp_maybe, joinPointBinding_maybe, joinPointBindings_maybe, isJoinPointBinding )
    
    42 42
     import GHC.Core.FVs     ( mkRuleInfo {- exprsFreeIds -} )
    
    43 43
     import GHC.Core.Rules   ( lookupRule, getRules )
    
    44 44
     import GHC.Core.Multiplicity
    
    ... ... @@ -316,8 +316,8 @@ simplLazyBind :: TopLevelFlag -> RecFlag
    316 316
     -- Precondition: Ids only, no TyVars; not a JoinId
    
    317 317
     -- Precondition: rhs obeys the let-can-float invariant
    
    318 318
     simplLazyBind top_lvl is_rec (bndr,unf_se) (bndr1,env) (rhs,rhs_se)
    
    319
    -  = assert (isId bndr )
    
    320
    -    assertPpr (not (isJoinId bndr)) (ppr bndr) $
    
    319
    +  = assert (isId bndr)
    
    320
    +    assertPpr (not $ isJoinPointBinding bndr) (ppr bndr) $
    
    321 321
         -- pprTrace "simplLazyBind" ((ppr bndr <+> ppr bndr1) $$ ppr rhs $$ ppr (seIdSubst rhs_se)) $
    
    322 322
         do  { let   !rhs_env     = rhs_se `setInScopeFromE` env -- See Note [Bangs in the Simplifier]
    
    323 323
                     (tvs, body) = case collectTyAndValBinders rhs of
    
    ... ... @@ -399,7 +399,7 @@ simplAuxBind :: String
    399 399
     -- Precondition: rhs satisfies the let-can-float invariant
    
    400 400
     
    
    401 401
     simplAuxBind _str env bndr new_rhs
    
    402
    -  | assertPpr (isId bndr && not (isJoinId bndr)) (ppr bndr) $
    
    402
    +  | assertPpr (isId bndr && not (isJoinPointBinding bndr)) (ppr bndr) $
    
    403 403
         isDeadBinder bndr   -- Not uncommon; e.g. case (a,b) of c { (p,q) -> p }
    
    404 404
       = return (emptyFloats env, env)    --  Here c is dead, and we avoid
    
    405 405
                                          --  creating the binding c = (a,b)
    
    ... ... @@ -1905,7 +1905,7 @@ simplNonRecE :: HasDebugCallStack
    1905 1905
     -- Otherwise it may or may not satisfy it.
    
    1906 1906
     
    
    1907 1907
     simplNonRecE env from_what bndr (rhs, rhs_se) body cont
    
    1908
    -  | assert (isId bndr && not (isJoinId bndr) ) $
    
    1908
    +  | assert (isId bndr && not (isJoinPointBinding bndr)) $
    
    1909 1909
         is_strict_bind
    
    1910 1910
       = -- Evaluate RHS strictly
    
    1911 1911
         simplExprF (rhs_se `setInScopeFromE` env) rhs
    
    ... ... @@ -1943,7 +1943,7 @@ simplRecE :: SimplEnv
    1943 1943
     -- Precondition: not a join-point binding
    
    1944 1944
     simplRecE env pairs body cont
    
    1945 1945
       = do  { let bndrs = map fst pairs
    
    1946
    -        ; massert (all (not . isJoinId) bndrs)
    
    1946
    +        ; massert (isNothing $ joinPointBindings_maybe pairs)
    
    1947 1947
             ; env1 <- simplRecBndrs env bndrs
    
    1948 1948
                     -- NB: bndrs' don't have unfoldings or rules
    
    1949 1949
                     -- We add them as we go down
    
    ... ... @@ -2051,7 +2051,7 @@ simplNonRecJoinPoint :: SimplEnv -> InId -> InExpr
    2051 2051
                          -> InExpr -> SimplCont
    
    2052 2052
                          -> SimplM (SimplFloats, OutExpr)
    
    2053 2053
     simplNonRecJoinPoint env bndr rhs body cont
    
    2054
    -   = assert (isJoinId bndr ) $
    
    2054
    +   = assert (isJoinPointBinding bndr) $
    
    2055 2055
          wrapJoinCont env cont $ \ env cont ->
    
    2056 2056
          do { -- We push join_cont into the join RHS and the body;
    
    2057 2057
               -- and wrap wrap_cont around the whole thing
    
    ... ... @@ -4574,22 +4574,24 @@ simplLetUnfolding env bind_cxt id new_rhs rhs_ty arity unf
    4574 4574
       | isStableUnfolding unf
    
    4575 4575
       = simplStableUnfolding env bind_cxt id rhs_ty arity unf
    
    4576 4576
     
    
    4577
    -  | freshly_born_join_point id
    
    4578
    -  = -- This is a tricky one!
    
    4579
    -    -- See wrinkle (JU1) in Note [Do not add unfoldings to join points at birth]
    
    4580
    -    return noUnfolding
    
    4581
    -
    
    4582 4577
       | isExitJoinId id
    
    4583 4578
       = -- See Note [Do not inline exit join points] in GHC.Core.Opt.Exitify
    
    4584 4579
         return noUnfolding
    
    4585 4580
     
    
    4586
    -  | otherwise
    
    4587
    -  = mkLetUnfolding env (bindContextLevel bind_cxt) VanillaSrc id is_join_point new_rhs
    
    4581
    +  | freshly_born_join_point
    
    4582
    +  = -- This is a tricky one!
    
    4583
    +    -- See wrinkle (JU1) in Note [Do not add unfoldings to join points at birth]
    
    4584
    +    return noUnfolding
    
    4588 4585
     
    
    4586
    +  | otherwise
    
    4587
    +  = mkLetUnfolding env (bindContextLevel bind_cxt) VanillaSrc id' is_join new_rhs'
    
    4589 4588
       where
    
    4590
    -    is_join_point = isJoinId id
    
    4591
    -    freshly_born_join_point id = is_join_point && isManyOccs (idOccInfo id)
    
    4592
    -      -- OLD: too_many_occs (OneOcc { occ_n_br = n }) = n > 10 -- See #23627
    
    4589
    +    (id', new_rhs', is_join) =
    
    4590
    +      case joinPointBinding_maybe id new_rhs of
    
    4591
    +        Nothing -> (id, new_rhs, False)
    
    4592
    +        Just (id', new_rhs') -> (id', new_rhs', True)
    
    4593
    +    freshly_born_join_point =
    
    4594
    +      is_join && (not (isJoinId id) || isManyOccs (idOccInfo id))
    
    4593 4595
     
    
    4594 4596
     -------------------
    
    4595 4597
     mkLetUnfolding :: SimplEnv -> TopLevelFlag -> UnfoldingSource
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -12,6 +12,7 @@ module GHC.Core.SimpleOpt (
    12 12
     
    
    13 13
             -- ** Join points
    
    14 14
             joinPointBinding_maybe, joinPointBindings_maybe,
    
    15
    +        isJoinPointBinding,
    
    15 16
     
    
    16 17
             -- ** Predicates on expressions
    
    17 18
             exprIsConApp_maybe, exprIsLiteral_maybe, exprIsLambda_maybe,
    
    ... ... @@ -1059,34 +1060,42 @@ and again its arity increases (#15517)
    1059 1060
     -}
    
    1060 1061
     
    
    1061 1062
     
    
    1062
    --- | Returns Just (bndr,rhs) if the binding is a join point:
    
    1063
    --- If it's a JoinId, just return it
    
    1064
    --- If it's not yet a JoinId but is always tail-called,
    
    1065
    ---    make it into a JoinId and return it.
    
    1066
    --- In the latter case, eta-expand the RHS if necessary, to make the
    
    1067
    --- lambdas explicit, as is required for join points
    
    1068
    ---
    
    1069
    --- Precondition: the InBndr has been occurrence-analysed,
    
    1070
    ---               so its OccInfo is valid
    
    1063
    +-- | Returns @Just (bndr,rhs)@ if the binding is a join point or can be made
    
    1064
    +-- into a join point (it is always tail called). In the latter case, eta-expand
    
    1065
    +-- the RHS if necessary, to make the lambdas explicit, as is required for join points.
    
    1071 1066
     joinPointBinding_maybe :: InBndr -> InExpr -> Maybe (InBndr, InExpr)
    
    1072 1067
     joinPointBinding_maybe bndr rhs
    
    1073 1068
       | not (isId bndr)
    
    1074 1069
       = Nothing
    
    1075 1070
     
    
    1071
    +  -- NB: the 'OccInfo' of the 'InBndr' may have been zapped, e.g. if we
    
    1072
    +  -- have inlined it. In this case, we may lose the join-point-hood of the
    
    1073
    +  -- original binder. A later occurrence analysis pass may recover it.
    
    1076 1074
       | isJoinId bndr
    
    1077
    -  = Just (bndr, rhs)
    
    1075
    +  = case tailCallInfo (idOccInfo bndr) of
    
    1076
    +      NoTailCallInfo -> Nothing
    
    1077
    +      AlwaysTailCalled {} -> Just (bndr, rhs)
    
    1078 1078
     
    
    1079 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
    
    1083
    -        join_bndr = bndr `asJoinId`        join_arity
    
    1083
    +        join_bndr = bndr `asJoinId`    join_arity
    
    1084 1084
                              `setIdDmdSig` etaConvertDmdSig str_arity str_sig
    
    1085 1085
       = Just (join_bndr, mkLams bndrs body)
    
    1086 1086
     
    
    1087 1087
       | otherwise
    
    1088 1088
       = Nothing
    
    1089 1089
     
    
    1090
    +isJoinPointBinding :: InBndr -> Bool
    
    1091
    +isJoinPointBinding bndr
    
    1092
    +  | not (isId bndr)
    
    1093
    +  = False
    
    1094
    +  | AlwaysTailCalled {} <- tailCallInfo (idOccInfo bndr)
    
    1095
    +  = True
    
    1096
    +  | otherwise
    
    1097
    +  = False
    
    1098
    +
    
    1090 1099
     joinPointBindings_maybe :: [(InBndr, InExpr)] -> Maybe [(InBndr, InExpr)]
    
    1091 1100
     joinPointBindings_maybe bndrs
    
    1092 1101
       = mapM (uncurry joinPointBinding_maybe) bndrs
    
    ... ... @@ -1443,7 +1452,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
    1443 1452
              in go subst' (float:floats) body (CC args mco)
    
    1444 1453
     
    
    1445 1454
         go subst floats (Let (NonRec bndr rhs) expr) cont
    
    1446
    -       | not (isJoinId bndr)
    
    1455
    +       | not (isJoinPointBinding bndr)
    
    1447 1456
              -- Crucial guard! See Note [Don't float join points]
    
    1448 1457
            = let rhs'            = subst_expr subst rhs
    
    1449 1458
                  (subst', bndr') = subst_bndr subst bndr