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

Commits:

5 changed files:

Changes:

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -915,7 +915,7 @@ lintCoreExpr (Lit lit)
    915 915
            ; return (literalType lit, zeroUE) }
    
    916 916
     
    
    917 917
     lintCoreExpr (Cast expr co)
    
    918
    -  = do { (expr_ty, ue) <- markAllJoinsBad (lintCoreExpr expr)
    
    918
    +  = do { (expr_ty, ue) <- lintCoreExpr expr -- SLD TODO markAllJoinsBad (lintCoreExpr expr)
    
    919 919
                 -- markAllJoinsBad: see Note [Join points and casts]
    
    920 920
     
    
    921 921
            ; lintCoercion co
    
    ... ... @@ -1146,7 +1146,7 @@ checkDeadIdOcc id
    1146 1146
     ------------------
    
    1147 1147
     lintJoinBndrType :: OutType -- Type of the body
    
    1148 1148
                      -> OutId   -- Possibly a join Id
    
    1149
    -                -> LintM ()
    
    1149
    +                 -> LintM ()
    
    1150 1150
     -- Checks that the return type of a join Id matches the body
    
    1151 1151
     -- E.g. join j x = rhs in body
    
    1152 1152
     --      The type of 'rhs' must be the same as the type of 'body'
    

  • compiler/GHC/Core/Opt/OccurAnal.hs
    ... ... @@ -42,7 +42,7 @@ import GHC.Core.Coercion
    42 42
     import GHC.Core.Type
    
    43 43
     import GHC.Core.TyCo.FVs    ( tyCoVarsOfMCo )
    
    44 44
     
    
    45
    -import GHC.Data.Maybe( orElse )
    
    45
    +import GHC.Data.Maybe( orElse, isNothing )
    
    46 46
     import GHC.Data.Graph.Directed ( SCC(..), Node(..)
    
    47 47
                                    , stronglyConnCompFromEdgedVerticesUniq
    
    48 48
                                    , stronglyConnCompFromEdgedVerticesUniqR )
    
    ... ... @@ -68,6 +68,7 @@ import GHC.Builtin.Names( runRWKey )
    68 68
     import GHC.Unit.Module( Module )
    
    69 69
     
    
    70 70
     import Data.List (mapAccumL)
    
    71
    +import qualified Data.List.NonEmpty as NE
    
    71 72
     import qualified Data.Semigroup as Semi
    
    72 73
     
    
    73 74
     {-
    
    ... ... @@ -2299,7 +2300,7 @@ occ_anal_lam_tail env (Cast expr co)
    2299 2300
                         _ -> usage1
    
    2300 2301
     
    
    2301 2302
              -- usage3: see Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
    
    2302
    -         usage3 = markAllNonTail usage2 -- SLD TODO
    
    2303
    +         usage3 = markAllQuasiTail usage2 -- SLD TODO
    
    2303 2304
     
    
    2304 2305
         in WUD usage3 (Cast expr' co)
    
    2305 2306
     
    
    ... ... @@ -2612,7 +2613,7 @@ occAnal env (Cast expr co)
    2612 2613
       = let (WUD usage expr') = occAnal env expr
    
    2613 2614
             usage1 = addManyOccs usage (coVarsOfCo co)
    
    2614 2615
                 -- usage1: see Note [Gather occurrences of coercion variables]
    
    2615
    -        usage2 = markAllNonTail usage1 -- SLD TODO
    
    2616
    +        usage2 = markAllQuasiTail usage1 -- SLD TODO
    
    2616 2617
                 -- usage2: see Note [Quasi join points]
    
    2617 2618
         in WUD usage2 (Cast expr' co)
    
    2618 2619
     
    
    ... ... @@ -3985,20 +3986,31 @@ adjustNonRecRhs mb_join_arity (WTUD (TUD rhs_ja uds) rhs)
    3985 3986
       where
    
    3986 3987
         exact_join =
    
    3987 3988
           case mb_join_arity of
    
    3988
    -        Nothing -> False
    
    3989
    -        Just ja' -> ja' == rhs_ja
    
    3990
    -
    
    3991
    -adjustTailUsage :: Bool        -- True <=> Exactly-matching join point; don't do markNonTail
    
    3989
    +        Nothing -> Nothing
    
    3990
    +        Just ja' ->
    
    3991
    +          if ja' == rhs_ja
    
    3992
    +          then Just TrueJoinPoint
    
    3993
    +          else Nothing
    
    3994
    +
    
    3995
    +adjustTailUsage :: HasDebugCallStack
    
    3996
    +                => Maybe JoinPointType
    
    3992 3997
                     -> CoreExpr    -- Rhs usage, AFTER occAnalLamTail
    
    3993 3998
                     -> UsageDetails
    
    3994 3999
                     -> UsageDetails
    
    3995
    -adjustTailUsage exact_join rhs uds
    
    4000
    +adjustTailUsage mb_join rhs uds
    
    3996 4001
       = -- c.f. occAnal (Lam {})
    
    3997 4002
         markAllInsideLamIf (not one_shot) $
    
    3998
    -    markAllNonTailIf (not exact_join) $
    
    4003
    +    mb_mark_nontail $
    
    3999 4004
         uds
    
    4000 4005
       where
    
    4001
    -    one_shot   = isOneShotFun rhs
    
    4006
    +    one_shot = isOneShotFun rhs
    
    4007
    +    mb_mark_nontail =
    
    4008
    +      case mb_join of
    
    4009
    +        Nothing -> markAllNonTail
    
    4010
    +        Just join_ty ->
    
    4011
    +          case join_ty of
    
    4012
    +            QuasiJoinPoint -> markAllQuasiTail
    
    4013
    +            TrueJoinPoint  -> id
    
    4002 4014
     
    
    4003 4015
     adjustTailArity :: Maybe JoinArity -> TailUsageDetails -> UsageDetails
    
    4004 4016
     adjustTailArity mb_rhs_ja (TUD ja usage) = markAllNonTailIf not_same_arity usage
    
    ... ... @@ -4036,11 +4048,8 @@ tagNonRecBinder :: TopLevelFlag -- At top level?
    4036 4048
     -- No-op on TyVars
    
    4037 4049
     -- Precondition: OccInfo is not IAmDead
    
    4038 4050
     tagNonRecBinder lvl occ bndr
    
    4039
    -  | okForJoinPoint lvl bndr tail_call_info
    
    4040
    -  , AlwaysTailCalled
    
    4041
    -    { tailCallArity = ar
    
    4042
    -    , tailCallJoinPointType = join_ty
    
    4043
    -    } <- tail_call_info
    
    4051
    +  | Just join_ty <- okForJoinPoint lvl bndr tail_call_info
    
    4052
    +  , AlwaysTailCalled { tailCallArity = ar } <- tail_call_info
    
    4044 4053
       = (setBinderOcc occ bndr,        JoinPoint join_ty ar)
    
    4045 4054
       | otherwise
    
    4046 4055
       = (setBinderOcc zapped_occ bndr, NotJoinPoint)
    
    ... ... @@ -4070,7 +4079,7 @@ tagRecBinders lvl body_uds details_s
    4070 4079
            = assertPpr (rhs_ja == joinRhsArity rhs) (ppr rhs_ja $$ ppr uds $$ ppr rhs) $
    
    4071 4080
              uds
    
    4072 4081
     
    
    4073
    -     will_be_joins :: Bool
    
    4082
    +     will_be_joins :: Maybe JoinPointType
    
    4074 4083
          will_be_joins = decideRecJoinPointHood lvl unadj_uds bndrs
    
    4075 4084
     
    
    4076 4085
          -- 2. Adjust usage details of each RHS, taking into account the
    
    ... ... @@ -4108,42 +4117,50 @@ setBinderOcc occ_info bndr
    4108 4117
     --
    
    4109 4118
     -- See Note [Invariants on join points] in "GHC.Core".
    
    4110 4119
     decideRecJoinPointHood :: TopLevelFlag -> UsageDetails
    
    4111
    -                       -> [CoreBndr] -> Bool
    
    4112
    -decideRecJoinPointHood lvl usage bndrs
    
    4113
    -  = all ok bndrs  -- Invariant 3: Either all are join points or none are
    
    4120
    +                       -> [CoreBndr] -> Maybe JoinPointType
    
    4121
    +decideRecJoinPointHood lvl usage bndrs = do
    
    4122
    +  bndrsNE <- NE.nonEmpty bndrs
    
    4123
    +  res <- Semi.sconcat <$> traverse ok bndrsNE  -- Invariant 3: Either all are join points or none are
    
    4124
    +  pprTraceM "decideRecJoinPointHood" $
    
    4125
    +    vcat [ text "bndrs:" <+> ppr bndrs
    
    4126
    +         , text "res:" <+> ppr res ]
    
    4127
    +  return res
    
    4114 4128
       where
    
    4115 4129
         ok bndr = okForJoinPoint lvl bndr (lookupTailCallInfo usage bndr)
    
    4116 4130
     
    
    4117
    -okForJoinPoint :: TopLevelFlag -> Id -> TailCallInfo -> Bool
    
    4131
    +okForJoinPoint :: TopLevelFlag -> Id -> TailCallInfo -> Maybe JoinPointType
    
    4118 4132
         -- See Note [Invariants on join points]; invariants cited by number below.
    
    4119 4133
         -- Invariant 2 is always satisfiable by the simplifier by eta expansion.
    
    4120 4134
     okForJoinPoint lvl bndr tail_call_info
    
    4121
    -  | isJoinId bndr        -- A current join point should still be one!
    
    4135
    +  | Just join_ty <- joinId_maybe bndr
    
    4136
    +  -- A current join point should still be one!
    
    4122 4137
       = warnPprTrace lost_join "Lost join point" lost_join_doc $
    
    4123
    -    True
    
    4124
    -  | valid_join
    
    4125
    -  = True
    
    4138
    +    Just join_ty
    
    4126 4139
       | otherwise
    
    4127
    -  = False
    
    4140
    +  = mb_valid_join
    
    4128 4141
       where
    
    4129
    -    valid_join | NotTopLevel <- lvl
    
    4130
    -               , AlwaysTailCalled { tailCallArity = arity } <- tail_call_info
    
    4131
    -
    
    4132
    -               , -- Invariant 1 as applied to LHSes of rules
    
    4133
    -                 all (ok_rule arity) (idCoreRules bndr)
    
    4134
    -
    
    4135
    -                 -- Invariant 2a: stable unfoldings
    
    4136
    -                  -- See Note [Join points and INLINE pragmas]
    
    4137
    -               , ok_unfolding arity (realIdUnfolding bndr)
    
    4138
    -
    
    4139
    -                 -- Invariant 4: Satisfies polymorphism rule
    
    4140
    -               , isValidJoinPointType arity (idType bndr)
    
    4141
    -               = True
    
    4142
    -               | otherwise
    
    4143
    -               = False
    
    4142
    +    mb_valid_join
    
    4143
    +      | NotTopLevel <- lvl
    
    4144
    +      , AlwaysTailCalled
    
    4145
    +        { tailCallArity = arity
    
    4146
    +        , tailCallJoinPointType = join_ty
    
    4147
    +        } <- tail_call_info
    
    4148
    +
    
    4149
    +      , -- Invariant 1 as applied to LHSes of rules
    
    4150
    +        all (ok_rule arity) (idCoreRules bndr)
    
    4151
    +
    
    4152
    +        -- Invariant 2a: stable unfoldings
    
    4153
    +        -- See Note [Join points and INLINE pragmas]
    
    4154
    +      , ok_unfolding arity (realIdUnfolding bndr)
    
    4155
    +
    
    4156
    +        -- Invariant 4: Satisfies polymorphism rule
    
    4157
    +      , isValidJoinPointType arity (idType bndr)
    
    4158
    +      = Just join_ty
    
    4159
    +      | otherwise
    
    4160
    +      = Nothing
    
    4144 4161
     
    
    4145 4162
         lost_join | JoinPoint { joinPointArity = ja } <- idJoinPointHood bndr
    
    4146
    -              = not valid_join ||
    
    4163
    +              = isNothing mb_valid_join ||
    
    4147 4164
                     (case tail_call_info of -- Valid join but arity differs
    
    4148 4165
                        AlwaysTailCalled { tailCallArity = ja' } -> ja /= ja'
    
    4149 4166
                        _ -> False)
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -2056,6 +2056,17 @@ is a join point, and what 'cont' is, in a value of type MaybeJoinCont
    2056 2056
     of a SpecConstr-generated RULE for a join point.
    
    2057 2057
     -}
    
    2058 2058
     
    
    2059
    +-- SLD TODO horrible logic that must be removed
    
    2060
    +peelJoinResTy :: Int -> Type -> Type
    
    2061
    +peelJoinResTy 0 ty = ty
    
    2062
    +peelJoinResTy n ty
    
    2063
    +  | Just (_bndr, inner_ty) <- splitForAllTyCoVar_maybe ty
    
    2064
    +  = peelJoinResTy n inner_ty
    
    2065
    +  | Just (_, _mult, _arg, res_ty) <- splitFunTy_maybe ty
    
    2066
    +  = peelJoinResTy (n-1) res_ty
    
    2067
    +  | otherwise
    
    2068
    +  = ty
    
    2069
    +
    
    2059 2070
     simplNonRecJoinPoint :: SimplEnv -> InId -> InExpr
    
    2060 2071
                          -> InExpr -> SimplCont
    
    2061 2072
                          -> SimplM (SimplFloats, OutExpr)
    
    ... ... @@ -2064,8 +2075,12 @@ simplNonRecJoinPoint env bndr rhs body cont
    2064 2075
          wrapJoinCont do_case_case env cont $ \ env cont ->
    
    2065 2076
          do { -- We push join_cont into the join RHS and the body;
    
    2066 2077
               -- and wrap wrap_cont around the whole thing
    
    2067
    -        ; let mult   = contHoleScaling cont
    
    2068
    -              res_ty = contResultType cont
    
    2078
    +        ; let (mult, res_ty)
    
    2079
    +                -- SLD TODO
    
    2080
    +                | Just QuasiJoinPoint <- occInfoJoinPointType_maybe (idOccInfo bndr)
    
    2081
    +                = (idMult bndr, peelJoinResTy (idJoinArity bndr) $ substTy env (idType bndr))
    
    2082
    +                | otherwise
    
    2083
    +                = (contHoleScaling cont, contResultType cont)
    
    2069 2084
             ; (env1, bndr1)    <- simplNonRecJoinBndr env bndr mult res_ty
    
    2070 2085
             ; (env2, bndr2)    <- addBndrRules env1 bndr bndr1 (BC_Join NonRecursive cont)
    
    2071 2086
             ; (floats1, env3)  <- simplJoinBind NonRecursive cont (bndr,env) (bndr2,env2) (rhs,env)
    
    ... ... @@ -2084,8 +2099,13 @@ simplRecJoinPoint :: SimplEnv -> [(InId, InExpr)]
    2084 2099
     simplRecJoinPoint env pairs body cont
    
    2085 2100
       = wrapJoinCont do_case_case env cont $ \ env cont ->
    
    2086 2101
         do { let bndrs  = map fst pairs
    
    2087
    -             mult   = contHoleScaling cont
    
    2088
    -             res_ty = contResultType cont
    
    2102
    +             (mult, res_ty)
    
    2103
    +                -- SLD TODO
    
    2104
    +                | [b] <- bndrs
    
    2105
    +                , Just QuasiJoinPoint <- occInfoJoinPointType_maybe (idOccInfo b)
    
    2106
    +                = (idMult b, peelJoinResTy (idJoinArity b) $ substTy env (idType b))
    
    2107
    +                | otherwise
    
    2108
    +                = (contHoleScaling cont, contResultType cont)
    
    2089 2109
            ; env1 <- simplRecJoinBndrs env bndrs mult res_ty
    
    2090 2110
                    -- NB: bndrs' don't have unfoldings or rules
    
    2091 2111
                    -- We add them as we go down
    
    ... ... @@ -2135,7 +2155,7 @@ trimJoinCont _ NotJoinPoint cont
    2135 2155
       = cont -- Not a jump
    
    2136 2156
     trimJoinCont var (JoinPoint { joinPointType = join_ty, joinPointArity = arity }) cont
    
    2137 2157
       | QuasiJoinPoint <- join_ty
    
    2138
    -  -- As per Note [Quasi join points], don't do any trimming for quasi join points.
    
    2158
    +  -- SLD TODO
    
    2139 2159
       = cont
    
    2140 2160
       | otherwise
    
    2141 2161
       = trim arity cont
    

  • compiler/GHC/Core/Opt/Simplify/Monad.hs
    ... ... @@ -214,7 +214,7 @@ newJoinId bndrs body_ty
    214 214
                  -- arity: See Note [Invariants on join points] invariant 2b, in GHC.Core
    
    215 215
                  join_arity = length bndrs
    
    216 216
                  details    = JoinId
    
    217
    -                            { joinIdType     = TrueJoinPoint -- SLD TODO this is very suspicious
    
    217
    +                            { joinIdType     = TrueJoinPoint -- SLD TODO this is suspicious
    
    218 218
                                 , joinIdArity    = join_arity
    
    219 219
                                 , joinIdCbvMarks = Nothing
    
    220 220
                                 }
    

  • compiler/GHC/Types/Id/Info.hs
    ... ... @@ -441,7 +441,7 @@ pprIdDetails other = brackets (pp other)
    441 441
        pp CoVarId                 = text "CoVarId"
    
    442 442
        pp (JoinId ty arity marks) = quasi <> text "JoinId" <> parens (int arity) <> parens (ppr marks)
    
    443 443
          where
    
    444
    -      quasi = case ty of { QuasiJoinPoint -> text "quasi"; TrueJoinPoint -> empty }
    
    444
    +      quasi = case ty of { QuasiJoinPoint -> text "Quasi"; TrueJoinPoint -> empty }
    
    445 445
     
    
    446 446
     {-
    
    447 447
     ************************************************************************