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

Commits:

19 changed files:

Changes:

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -935,7 +935,12 @@ lintCoreExpr (Tick tickish expr)
    935 935
           --  ; when block_joins
    
    936 936
            ; pure r}
    
    937 937
       where
    
    938
    -    block_joins = not (tickishCanScopeJoin tickish)
    
    938
    +    block_joins
    
    939
    +      | ProfNote {} <- tickish
    
    940
    +      = False -- Turns a true join point into a quasi join point.
    
    941
    +              -- SLD TODO: proper Core Lint support for quasi join points.
    
    942
    +      | otherwise
    
    943
    +      = not (tickishCanScopeJoin tickish)
    
    939 944
           -- TODO Consider whether this is the correct rule. It is consistent with
    
    940 945
           -- the simplifier's behaviour - cost-centre-scoped ticks become part of
    
    941 946
           -- the continuation, and thus they behave like part of an evaluation
    
    ... ... @@ -1021,22 +1026,27 @@ lintCoreExpr e@(App _ _)
    1021 1026
     
    
    1022 1027
            ; return app_pair}
    
    1023 1028
       where
    
    1024
    -    skipTick t = case collectFunSimple e of
    
    1025
    -      (Var v) -> etaExpansionTick v t
    
    1026
    -      _ -> tickishFloatable t
    
    1027
    -    (fun, args, _source_ticks) = collectArgsTicks skipTick e
    
    1028
    -      -- We must look through source ticks to avoid #21152, for example:
    
    1029
    +    skipTick t =
    
    1030
    +      case collectFunSimple e of
    
    1031
    +        Var v -> canCollectArgsThroughTick v t
    
    1032
    +        _ -> tickishFloatable t
    
    1033
    +    (fun, args, _ticks) = collectArgsTicks skipTick e
    
    1034
    +      -- We must look through ticks, using similar logic as CorePrep does,
    
    1035
    +      -- otherwise we may fail to spot a saturated application.
    
    1036
    +      --
    
    1037
    +      --   1. Look through floatable ticks, as per Note [Eta expansion and source notes]
    
    1038
    +      --      in GHC.Core.Opt.Arity. We need to do this to avoid e.g.:
    
    1039
    +      --
    
    1040
    +      --        reallyUnsafePtrEquality
    
    1041
    +      --          = \ @a ->
    
    1042
    +      --              (src<loc> reallyUnsafePtrEquality#)
    
    1043
    +      --                @Lifted @a @Lifted @a
    
    1029 1044
           --
    
    1030
    -      -- reallyUnsafePtrEquality
    
    1031
    -      --   = \ @a ->
    
    1032
    -      --       (src<loc> reallyUnsafePtrEquality#)
    
    1033
    -      --         @Lifted @a @Lifted @a
    
    1045
    +      --   2. Look through profiling ticks when the head of the application must
    
    1046
    +      --      always remain saturated (e.g. a primop or a join point), as per
    
    1047
    +      --      Note [Ticks and mandatory eta expansion] in GHC.CoreToStg.Prep.
    
    1034 1048
           --
    
    1035
    -      -- To do this, we use `collectArgsTicks tickishFloatable` to match
    
    1036
    -      -- the eta expansion behaviour, as per Note [Eta expansion and source notes]
    
    1037
    -      -- in GHC.Core.Opt.Arity.
    
    1038
    -      -- Sadly this was not quite enough. So we now also accept things that CorePrep will allow.
    
    1039
    -      -- See Note [Ticks and mandatory eta expansion]
    
    1049
    +      -- To do this, we use 'canCollectArgsThroughTick', as CorePrep does.
    
    1040 1050
     
    
    1041 1051
     lintCoreExpr (Lam var expr)
    
    1042 1052
       = markAllJoinsBad $
    

  • compiler/GHC/Core/Opt/Exitify.hs
    ... ... @@ -226,7 +226,7 @@ exitifyRec in_scope pairs
    226 226
                  let rhs   = mkLams abs_vars e
    
    227 227
                      avoid = in_scope `extendInScopeSetList` captured
    
    228 228
                  -- Remember this binding under a suitable name
    
    229
    -           ; v <- addExit avoid TrueJoinPoint (length abs_vars) rhs
    
    229
    +           ; v <- addExit avoid (length abs_vars) rhs
    
    230 230
                  -- And jump to it from here
    
    231 231
                ; return $ mkVarApps (Var v) abs_vars }
    
    232 232
     
    
    ... ... @@ -262,7 +262,7 @@ exitifyRec in_scope pairs
    262 262
     --  * the free variables of the whole joinrec
    
    263 263
     --  * any bound variables (captured)
    
    264 264
     --  * any exit join points created so far.
    
    265
    -mkExitJoinId :: InScopeSet -> Type -> JoinType -> JoinArity -> ExitifyM JoinId
    
    265
    +mkExitJoinId :: InScopeSet -> Type -> JoinPointType -> JoinArity -> ExitifyM JoinId
    
    266 266
     mkExitJoinId in_scope ty join_ty join_arity = do
    
    267 267
         fs <- get
    
    268 268
         let avoid = in_scope `extendInScopeSetList` (map fst fs)
    
    ... ... @@ -273,11 +273,11 @@ mkExitJoinId in_scope ty join_ty join_arity = do
    273 273
           asJoinId (mkSysLocal (fsLit "exit") initExitJoinUnique ManyTy ty)
    
    274 274
             join_ty join_arity
    
    275 275
     
    
    276
    -addExit :: InScopeSet -> JoinType -> JoinArity -> CoreExpr -> ExitifyM JoinId
    
    277
    -addExit in_scope join_ty join_arity rhs = do
    
    276
    +addExit :: InScopeSet -> JoinArity -> CoreExpr -> ExitifyM JoinId
    
    277
    +addExit in_scope join_arity rhs = do
    
    278 278
         -- Pick a suitable name
    
    279 279
         let ty = exprType rhs
    
    280
    -    v <- mkExitJoinId in_scope ty join_ty join_arity
    
    280
    +    v <- mkExitJoinId in_scope ty TrueJoinPoint join_arity
    
    281 281
         fs <- get
    
    282 282
         put ((v,rhs):fs)
    
    283 283
         return v
    

  • compiler/GHC/Core/Opt/OccurAnal.hs
    ... ... @@ -1126,7 +1126,7 @@ occAnalNonRecRhs !env lvl imp_rule_edges mb_join bndr rhs
    1126 1126
         -- returned by of occAnalLamTail. It's totally OK for them to mismatch;
    
    1127 1127
         -- hence adjust the UDs from the RHS
    
    1128 1128
     
    
    1129
    -    WUD adj_rhs_uds final_rhs = adjustNonRecRhs mb_join $
    
    1129
    +    WUD adj_rhs_uds final_rhs = adjustNonRecRhs (joinPointHoodArity mb_join) $
    
    1130 1130
                                     occAnalLamTail rhs_env rhs
    
    1131 1131
         final_bndr_with_rules
    
    1132 1132
           | noBinderSwaps env = bndr -- See Note [Unfoldings and rules]
    
    ... ... @@ -1140,7 +1140,8 @@ occAnalNonRecRhs !env lvl imp_rule_edges mb_join bndr rhs
    1140 1140
         -- See Note [Join points and unfoldings/rules]
    
    1141 1141
         unf = idUnfolding bndr
    
    1142 1142
         WTUD unf_tuds unf1 = occAnalUnfolding rhs_env unf
    
    1143
    -    adj_unf_uds = adjustTailArity mb_join unf_tuds
    
    1143
    +    adj_unf_uds = adjustTailArity mb_join_arity unf_tuds
    
    1144
    +    mb_join_arity = joinPointHoodArity mb_join
    
    1144 1145
     
    
    1145 1146
         --------- Rules ---------
    
    1146 1147
         -- See Note [Rules are extra RHSs] and Note [Rule dependency info]
    
    ... ... @@ -1160,7 +1161,7 @@ occAnalNonRecRhs !env lvl imp_rule_edges mb_join bndr rhs
    1160 1161
     
    
    1161 1162
         adj_rule_uds :: [UsageDetails]
    
    1162 1163
         adj_rule_uds = imp_rule_uds ++
    
    1163
    -                   [ l `andUDs` adjustTailArity mb_join r
    
    1164
    +                   [ l `andUDs` adjustTailArity mb_join_arity r
    
    1164 1165
                        | (_,l,r) <- rules_w_uds ]
    
    1165 1166
     
    
    1166 1167
     mkNonRecRhsCtxt :: TopLevelFlag -> Id -> Unfolding -> OccEncl
    
    ... ... @@ -1215,7 +1216,7 @@ occAnalRec !_ lvl
    1215 1216
       = WUD body_uds binds
    
    1216 1217
       | otherwise
    
    1217 1218
       = let (bndr', mb_join) = tagNonRecBinder lvl occ bndr
    
    1218
    -        !(WUD rhs_uds' rhs') = adjustNonRecRhs mb_join wtuds
    
    1219
    +        !(WUD rhs_uds' rhs') = adjustNonRecRhs (joinPointHoodArity mb_join) wtuds
    
    1219 1220
         in WUD (body_uds `andUDs` rhs_uds')
    
    1220 1221
                (NonRec bndr' rhs' : binds)
    
    1221 1222
       where
    
    ... ... @@ -1831,7 +1832,7 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs)
    1831 1832
         unf = realIdUnfolding bndr -- realIdUnfolding: Ignore loop-breaker-ness
    
    1832 1833
                                    -- here because that is what we are setting!
    
    1833 1834
         WTUD unf_tuds unf' = occAnalUnfolding rhs_env unf
    
    1834
    -    adj_unf_uds = adjustTailArity (JoinPoint True rhs_ja) unf_tuds
    
    1835
    +    adj_unf_uds = adjustTailArity (Just rhs_ja) unf_tuds
    
    1835 1836
           -- `rhs_ja` is `joinRhsArity rhs` and is the prediction for source MAr
    
    1836 1837
           -- of Note [Join arity prediction based on joinRhsArity]
    
    1837 1838
     
    
    ... ... @@ -1846,7 +1847,7 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs)
    1846 1847
         -- `rhs_ja` is `joinRhsArity rhs'` and is the prediction for source MAr
    
    1847 1848
         -- of Note [Join arity prediction based on joinRhsArity]
    
    1848 1849
         rules_w_uds :: [(CoreRule, UsageDetails, UsageDetails)]
    
    1849
    -    rules_w_uds = [ (r,l,adjustTailArity (JoinPoint True rhs_ja) rhs_wuds)
    
    1850
    +    rules_w_uds = [ (r,l,adjustTailArity (Just rhs_ja) rhs_wuds)
    
    1850 1851
                       | rule <- idCoreRules bndr
    
    1851 1852
                       , let (r,l,rhs_wuds) = occAnalRule rhs_env rule ]
    
    1852 1853
         rules'      = map fstOf3 rules_w_uds
    
    ... ... @@ -2298,7 +2299,7 @@ occ_anal_lam_tail env (Cast expr co)
    2298 2299
                         _ -> usage1
    
    2299 2300
     
    
    2300 2301
              -- usage3: see Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
    
    2301
    -         usage3 = markAllQuasiTail usage2
    
    2302
    +         usage3 = markAllQuasiTail usage2 -- SLD TODO
    
    2302 2303
     
    
    2303 2304
         in WUD usage3 (Cast expr' co)
    
    2304 2305
     
    
    ... ... @@ -2606,19 +2607,11 @@ occAnal env (Tick tickish body)
    2606 2607
     
    
    2607 2608
         usage_lam = markAllNonTail (markAllInsideLam usage)
    
    2608 2609
     
    
    2609
    -    -- TODO There may be ways to make ticks and join points play
    
    2610
    -    -- nicer together, but right now there are problems:
    
    2611
    -    --   let j x = ... in tick<t> (j 1)
    
    2612
    -    -- Making j a join point may cause the simplifier to drop t
    
    2613
    -    -- (if the tick is put into the continuation). So we don't
    
    2614
    -    -- count j 1 as a tail call.
    
    2615
    -    -- See #14242.
    
    2616
    -
    
    2617 2610
     occAnal env (Cast expr co)
    
    2618 2611
       = let (WUD usage expr') = occAnal env expr
    
    2619 2612
             usage1 = addManyOccs usage (coVarsOfCo co)
    
    2620 2613
                 -- usage1: see Note [Gather occurrences of coercion variables]
    
    2621
    -        usage2 = markAllQuasiTail usage1
    
    2614
    +        usage2 = markAllQuasiTail usage1 -- SLD TODO
    
    2622 2615
                 -- usage2: see Note [Quasi join points]
    
    2623 2616
         in WUD usage2 (Cast expr' co)
    
    2624 2617
     
    
    ... ... @@ -2626,7 +2619,7 @@ occAnal env app@(App _ _)
    2626 2619
       = occAnalApp env (collectArgsTicks tickishFloatable app)
    
    2627 2620
     
    
    2628 2621
     occAnal env expr@(Lam {})
    
    2629
    -  = adjustNonRecRhs NotJoinPoint $ -- NotJoinPoint <=> markAllManyNonTail
    
    2622
    +  = adjustNonRecRhs Nothing $ -- Nothing <=> markAllManyNonTail
    
    2630 2623
         occAnalLamTail env expr
    
    2631 2624
     
    
    2632 2625
     occAnal env (Case scrut bndr ty alts)
    
    ... ... @@ -2754,7 +2747,8 @@ occAnalApp env (Var fun, args, ticks)
    2754 2747
       --     This caused #18296
    
    2755 2748
       | fun `hasKey` runRWKey
    
    2756 2749
       , [t1, t2, arg]  <- args
    
    2757
    -  , WUD usage arg' <- adjustNonRecRhs (JoinPoint True 1) $ occAnalLamTail env arg
    
    2750
    +  , WUD usage arg' <- adjustNonRecRhs (Just 1) $ occAnalLamTail env arg
    
    2751
    +  -- SLD TODO TrueJoinPoint OK here??
    
    2758 2752
       = let app_out = mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']
    
    2759 2753
         in WUD usage app_out
    
    2760 2754
     
    
    ... ... @@ -3814,8 +3808,8 @@ mkOneOcc !env id int_cxt arity
    3814 3808
             , lo_tail =
    
    3815 3809
                 AlwaysTailCalled
    
    3816 3810
                   { tailCallArity = arity
    
    3817
    -              , trueTailCall = True
    
    3818
    -                 -- ^ Start off as a true join point.
    
    3811
    +              , tailCallJoinPointType = TrueJoinPoint
    
    3812
    +                 -- Start off as a true join point.
    
    3819 3813
                      -- Updated by occurrence analysis.
    
    3820 3814
                      --
    
    3821 3815
                      -- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
    
    ... ... @@ -3903,7 +3897,11 @@ maybeZapTailCallInfo tail_info0 z_tail id_unique =
    3903 3897
         Just MarkNonTail -> NoTailCallInfo
    
    3904 3898
     
    
    3905 3899
         -- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
    
    3906
    -    Just MarkQuasi -> tail_info0 { trueTailCall = False }
    
    3900
    +    Just MarkQuasi ->
    
    3901
    +      case tail_info0 of
    
    3902
    +        NoTailCallInfo -> NoTailCallInfo
    
    3903
    +        atc@AlwaysTailCalled {} ->
    
    3904
    +          atc { tailCallJoinPointType = QuasiJoinPoint }
    
    3907 3905
     
    
    3908 3906
         Nothing -> tail_info0
    
    3909 3907
     
    
    ... ... @@ -3974,7 +3972,7 @@ lookupOccInfoByUnique (UD { ud_env = env
    3974 3972
     -------------------
    
    3975 3973
     -- See Note [Adjusting right-hand sides]
    
    3976 3974
     
    
    3977
    -adjustNonRecRhs :: JoinPointHood
    
    3975
    +adjustNonRecRhs :: Maybe JoinArity
    
    3978 3976
                     -> WithTailUsageDetails CoreExpr
    
    3979 3977
                     -> WithUsageDetails CoreExpr
    
    3980 3978
     -- ^ This function concentrates shared logic between occAnalNonRecBind and the
    
    ... ... @@ -3985,8 +3983,8 @@ adjustNonRecRhs mb_join_arity (WTUD (TUD rhs_ja uds) rhs)
    3985 3983
       where
    
    3986 3984
         exact_join =
    
    3987 3985
           case mb_join_arity of
    
    3988
    -        NotJoinPoint -> False
    
    3989
    -        JoinPoint { joinPointArity = ja' } -> ja' == rhs_ja
    
    3986
    +        Nothing -> False
    
    3987
    +        Just ja' -> ja' == rhs_ja
    
    3990 3988
     
    
    3991 3989
     adjustTailUsage :: Bool        -- True <=> Exactly-matching join point; don't do markNonTail
    
    3992 3990
                     -> CoreExpr    -- Rhs usage, AFTER occAnalLamTail
    
    ... ... @@ -4000,12 +3998,12 @@ adjustTailUsage exact_join rhs uds
    4000 3998
       where
    
    4001 3999
         one_shot   = isOneShotFun rhs
    
    4002 4000
     
    
    4003
    -adjustTailArity :: JoinPointHood -> TailUsageDetails -> UsageDetails
    
    4001
    +adjustTailArity :: Maybe JoinArity -> TailUsageDetails -> UsageDetails
    
    4004 4002
     adjustTailArity mb_rhs_ja (TUD ja usage) = markAllNonTailIf not_same_arity usage
    
    4005 4003
       where
    
    4006 4004
         not_same_arity = case mb_rhs_ja of
    
    4007
    -      NotJoinPoint -> True
    
    4008
    -      JoinPoint { joinPointArity = ja' } -> ja' /= ja
    
    4005
    +      Nothing -> True
    
    4006
    +      Just ja' -> ja' /= ja
    
    4009 4007
     
    
    4010 4008
     type IdWithOccInfo = Id
    
    4011 4009
     
    
    ... ... @@ -4037,8 +4035,11 @@ tagNonRecBinder :: TopLevelFlag -- At top level?
    4037 4035
     -- Precondition: OccInfo is not IAmDead
    
    4038 4036
     tagNonRecBinder lvl occ bndr
    
    4039 4037
       | okForJoinPoint lvl bndr tail_call_info
    
    4040
    -  , AlwaysTailCalled { tailCallArity = ar, trueTailCall = true } <- tail_call_info
    
    4041
    -  = (setBinderOcc occ bndr,        JoinPoint true ar)
    
    4038
    +  , AlwaysTailCalled
    
    4039
    +    { tailCallArity = ar
    
    4040
    +    , tailCallJoinPointType = join_ty
    
    4041
    +    } <- tail_call_info
    
    4042
    +  = (setBinderOcc occ bndr,        JoinPoint join_ty ar)
    
    4042 4043
       | otherwise
    
    4043 4044
       = (setBinderOcc zapped_occ bndr, NotJoinPoint)
    
    4044 4045
      where
    
    ... ... @@ -4229,5 +4230,5 @@ orLocalOcc occ1 occ2 = andLocalOcc occ1 occ2
    4229 4230
     
    
    4230 4231
     andTailCallInfo :: TailCallInfo -> TailCallInfo -> TailCallInfo
    
    4231 4232
     andTailCallInfo (AlwaysTailCalled arity1 true1) (AlwaysTailCalled arity2 true2)
    
    4232
    -  | arity1 == arity2 = AlwaysTailCalled arity1 (true1 && true2)
    
    4233
    +  | arity1 == arity2 = AlwaysTailCalled arity1 (true1 Semi.<> true2)
    
    4233 4234
     andTailCallInfo _ _  = NoTailCallInfo

  • compiler/GHC/Core/Opt/SetLevels.hs
    ... ... @@ -1889,11 +1889,10 @@ newPolyBndrs dest_lvl
    1889 1889
         dest_is_top = isTopLvl dest_lvl
    
    1890 1890
         transfer_join_info bndr new_bndr
    
    1891 1891
           | JoinPoint
    
    1892
    -        { isTrueJoinPoint = true_join
    
    1892
    +        { joinPointType  = join_ty
    
    1893 1893
             , joinPointArity = join_arity }
    
    1894 1894
               <- idJoinPointHood bndr
    
    1895 1895
           , not dest_is_top
    
    1896
    -      , let join_ty = if true_join then TrueJoinPoint else QuasiJoinPoint
    
    1897 1896
           = asJoinId new_bndr
    
    1898 1897
               join_ty
    
    1899 1898
               ( join_arity + length abs_vars )
    

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -493,8 +493,8 @@ instance Outputable SimplSR where
    493 493
         where
    
    494 494
           pp_mj = case mj of
    
    495 495
                     NotJoinPoint -> empty
    
    496
    -                JoinPoint true_join n
    
    497
    -                  -> (if true_join then empty else text "[Quasi]") <> parens (int n)
    
    496
    +                JoinPoint { joinPointType = join_ty, joinPointArity = n }
    
    497
    +                  -> ppr join_ty <> parens (int n)
    
    498 498
     
    
    499 499
       ppr (ContEx _tv _cv _id e) = vcat [text "ContEx" <+> ppr e {-,
    
    500 500
                                     ppr (filter_env tv), ppr (filter_env id) -}]
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -2073,7 +2073,7 @@ simplNonRecJoinPoint env bndr rhs body cont
    2073 2073
             ; return (floats1 `addFloats` floats2, body') }
    
    2074 2074
       where
    
    2075 2075
         do_case_case
    
    2076
    -      | Just True <- occInfoIsTrueJoinPoint (idOccInfo bndr)
    
    2076
    +      | Just TrueJoinPoint <- occInfoJoinPointType_maybe (idOccInfo bndr)
    
    2077 2077
           = seCaseCase env
    
    2078 2078
           | otherwise
    
    2079 2079
           = False
    
    ... ... @@ -2094,7 +2094,7 @@ simplRecJoinPoint env pairs body cont
    2094 2094
            ; return (floats1 `addFloats` floats2, body') }
    
    2095 2095
       where
    
    2096 2096
         do_case_case =
    
    2097
    -      if all ((== Just True) . occInfoIsTrueJoinPoint . idOccInfo . fst) pairs
    
    2097
    +      if all ((== Just TrueJoinPoint) . occInfoJoinPointType_maybe . idOccInfo . fst) pairs
    
    2098 2098
           then seCaseCase env
    
    2099 2099
           else False
    
    2100 2100
     
    
    ... ... @@ -2133,10 +2133,12 @@ trimJoinCont :: Id -- Used only in error message
    2133 2133
     
    
    2134 2134
     trimJoinCont _ NotJoinPoint cont
    
    2135 2135
       = cont -- Not a jump
    
    2136
    -trimJoinCont var (JoinPoint { isTrueJoinPoint = true_join, joinPointArity = arity }) cont
    
    2137
    -  = assertPpr true_join
    
    2138
    -      (text "trimJoinCont: unexpected quasi join point:" <+> ppr var) $
    
    2139
    -    trim arity cont
    
    2136
    +trimJoinCont var (JoinPoint { joinPointType = join_ty, joinPointArity = arity }) cont
    
    2137
    +  | QuasiJoinPoint <- join_ty
    
    2138
    +  -- SLD TODO: not sure why we can end up here. Needs further investigation.
    
    2139
    +  = cont
    
    2140
    +  | otherwise
    
    2141
    +  = trim arity cont
    
    2140 2142
       where
    
    2141 2143
         trim 0 cont@(Stop {})
    
    2142 2144
           = cont
    
    ... ... @@ -2246,7 +2248,7 @@ Note [Join points and case-of-case]:
    2246 2248
     This transformation is not valid if the occurrences of 'j' in 'body' appear:
    
    2247 2249
     
    
    2248 2250
       1. under casts (see #26422)
    
    2249
    -  2. under profiling ticks (see #26693, #26157, #26642)
    
    2251
    +  2. under profiling ticks (see #14242, #26157, #26642, #26693)
    
    2250 2252
     
    
    2251 2253
     For example, consider (a minimisation of) the program in #26693:
    
    2252 2254
     
    
    ... ... @@ -2312,7 +2314,7 @@ we proceed as follows:
    2312 2314
       2. In the simplifier, when we come across a join point binding (in either
    
    2313 2315
          'simplNonRecJoinPoint' or 'simplRecJoinPoint'), we retrieve the information
    
    2314 2316
          of whether this is a true join point or a quasi join point using
    
    2315
    -     'occInfoIsTrueJoinPoint'.
    
    2317
    +     'occInfoJoinPointType_maybe'.
    
    2316 2318
     
    
    2317 2319
          If we are dealing with a quasi join point, we switch off the case-of-case
    
    2318 2320
          transformation.
    

  • compiler/GHC/Core/Opt/Simplify/Monad.hs
    ... ... @@ -25,7 +25,7 @@ import GHC.Prelude
    25 25
     import GHC.Types.Var       ( Var, isId, mkLocalVar )
    
    26 26
     import GHC.Types.Name      ( mkSystemVarName )
    
    27 27
     import GHC.Types.Id        ( Id, mkSysLocalOrCoVarM )
    
    28
    -import GHC.Types.Id.Info   ( IdDetails(..), vanillaIdInfo, setArityInfo, JoinType (..) )
    
    28
    +import GHC.Types.Id.Info   ( IdDetails(..), vanillaIdInfo, setArityInfo )
    
    29 29
     import GHC.Core.Type       ( Type, Mult )
    
    30 30
     import GHC.Core.Opt.Stats
    
    31 31
     import GHC.Core.Rules
    

  • compiler/GHC/Core/Opt/SpecConstr.hs
    ... ... @@ -46,7 +46,7 @@ import GHC.Types.InlinePragma
    46 46
     import GHC.Types.Error (DiagnosticReason(..))
    
    47 47
     import GHC.Types.Literal ( litIsLifted )
    
    48 48
     import GHC.Types.Id
    
    49
    -import GHC.Types.Id.Info ( IdDetails(..), JoinType (..) )
    
    49
    +import GHC.Types.Id.Info ( IdDetails(..) )
    
    50 50
     import GHC.Types.Id.Make ( voidArgId, voidPrimId )
    
    51 51
     import GHC.Types.Var.Env
    
    52 52
     import GHC.Types.Var.Set
    
    ... ... @@ -1993,9 +1993,8 @@ spec_one env fn arg_bndrs body (call_pat, rule_number)
    1993 1993
                   spec_id_ty = mkLamTypes spec_lam_args spec_body_ty
    
    1994 1994
                   spec_arity = count isId spec_lam_args
    
    1995 1995
                   spec_join_arity
    
    1996
    -                | Just ty <- joinId_maybe fn
    
    1997
    -                , let is_true = case ty of { TrueJoinPoint -> True; QuasiJoinPoint -> False }
    
    1998
    -                = JoinPoint { isTrueJoinPoint = is_true, joinPointArity = length spec_call_args }
    
    1996
    +                | Just join_ty <- joinId_maybe fn
    
    1997
    +                = JoinPoint { joinPointType = join_ty, joinPointArity = length spec_call_args }
    
    1999 1998
                     | otherwise
    
    2000 1999
                     = NotJoinPoint
    
    2001 2000
                   spec_id    = setCbvCandidate $
    

  • compiler/GHC/Core/Opt/WorkWrap.hs
    ... ... @@ -844,10 +844,10 @@ mkWWBindPair ww_opts fn_id fn_info fn_args fn_body work_uniq div
    844 844
           -- inl_rule:   it does not make sense for workers to be constructorlike.
    
    845 845
     
    
    846 846
         work_join_arity
    
    847
    -      | Just ty <- joinId_maybe fn_id =
    
    848
    -        let true_join = case ty of { TrueJoinPoint -> True; QuasiJoinPoint -> False }
    
    849
    -        in JoinPoint true_join join_arity
    
    850
    -      | otherwise      = NotJoinPoint
    
    847
    +      | Just join_ty <- joinId_maybe fn_id
    
    848
    +      = JoinPoint join_ty join_arity
    
    849
    +      | otherwise
    
    850
    +      = NotJoinPoint
    
    851 851
           -- worker is join point iff wrapper is join point
    
    852 852
           -- (see Note [Don't w/w join points for CPR])
    
    853 853
     
    

  • compiler/GHC/Core/Ppr.hs
    ... ... @@ -308,13 +308,21 @@ ppr_expr add_par (Let bind expr)
    308 308
         sep [hang (keyword bind <+> char '{') 2 (ppr_bind noAnn bind <+> text "} in"),
    
    309 309
              pprCoreExpr expr]
    
    310 310
       where
    
    311
    -    keyword (NonRec b _)
    
    312
    -     | isJoinPoint (bndrIsJoin_maybe b) = text "join"
    
    313
    -     | otherwise                        = text "let"
    
    314
    -    keyword (Rec pairs)
    
    315
    -     | ((b,_):_) <- pairs
    
    316
    -     , isJoinPoint (bndrIsJoin_maybe b) = text "joinrec"
    
    317
    -     | otherwise                        = text "letrec"
    
    311
    +    keyword (NonRec b _) =
    
    312
    +      case bndrIsJoin_maybe b of
    
    313
    +        NotJoinPoint -> text "let"
    
    314
    +        JoinPoint { joinPointType = join_ty } ->
    
    315
    +          case join_ty of
    
    316
    +            TrueJoinPoint -> text "join"
    
    317
    +            QuasiJoinPoint -> text "quasijoin"
    
    318
    +    keyword (Rec ((b,_):_)) =
    
    319
    +      case bndrIsJoin_maybe b of
    
    320
    +        NotJoinPoint -> text "letrec"
    
    321
    +        JoinPoint { joinPointType = join_ty } ->
    
    322
    +          case join_ty of
    
    323
    +            TrueJoinPoint -> text "joinrec"
    
    324
    +            QuasiJoinPoint -> text "quasijoinrec"
    
    325
    +    keyword (Rec _) = text "letrec"
    
    318 326
     
    
    319 327
     ppr_expr add_par (Tick tickish expr)
    
    320 328
       = sdocOption sdocSuppressTicks $ \case
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -38,7 +38,10 @@ import GHC.Core.Coercion hiding ( substCo, substCoVarBndr )
    38 38
     
    
    39 39
     import GHC.Types.Literal
    
    40 40
     import GHC.Types.Id
    
    41
    -import GHC.Types.Id.Info  ( realUnfoldingInfo, setUnfoldingInfo, setRuleInfo, IdInfo (..), JoinType (..) )
    
    41
    +import GHC.Types.Id.Info
    
    42
    +  ( IdInfo(..)
    
    43
    +  , realUnfoldingInfo, setUnfoldingInfo, setRuleInfo
    
    44
    +  )
    
    42 45
     import GHC.Types.InlinePragma ( isAlwaysActive )
    
    43 46
     import GHC.Types.Var      ( isNonCoVarId )
    
    44 47
     import GHC.Types.Var.Set
    
    ... ... @@ -1078,12 +1081,11 @@ joinPointBinding_maybe bndr rhs
    1078 1081
     
    
    1079 1082
       | AlwaysTailCalled
    
    1080 1083
         { tailCallArity = join_arity
    
    1081
    -    , trueTailCall  = is_true_tail }
    
    1084
    +    , tailCallJoinPointType = join_ty }
    
    1082 1085
           <- tailCallInfo (idOccInfo bndr)
    
    1083 1086
       , (bndrs, body) <- etaExpandToJoinPoint join_arity rhs
    
    1084 1087
       , let str_sig   = idDmdSig bndr
    
    1085 1088
             str_arity = count isId bndrs  -- Strictness demands are for Ids only
    
    1086
    -        join_ty = if is_true_tail then TrueJoinPoint else QuasiJoinPoint
    
    1087 1089
             join_bndr =
    
    1088 1090
               (asJoinId bndr join_ty join_arity)
    
    1089 1091
                 `setIdDmdSig` etaConvertDmdSig str_arity str_sig
    

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -34,7 +34,7 @@ module GHC.Core.Utils (
    34 34
             exprIsTickedString, exprIsTickedString_maybe,
    
    35 35
             exprIsTopLevelBindable,
    
    36 36
             exprIsUnaryClassFun, isUnaryClassId,
    
    37
    -        altsAreExhaustive, etaExpansionTick,
    
    37
    +        altsAreExhaustive, canCollectArgsThroughTick,
    
    38 38
             cantEtaReduceFun,
    
    39 39
     
    
    40 40
             -- * Equality
    
    ... ... @@ -2076,14 +2076,17 @@ altsAreExhaustive (Alt con1 _ _ : alts)
    2076 2076
           -- we behave conservatively here -- I don't think it's important
    
    2077 2077
           -- enough to deserve special treatment
    
    2078 2078
     
    
    2079
    --- | Should we look past this tick when eta-expanding the given function?
    
    2079
    +-- | Should we look past this tick when collecting arguments
    
    2080
    +-- for the given function?
    
    2080 2081
     --
    
    2081 2082
     -- See Note [Ticks and mandatory eta expansion]
    
    2082
    --- Takes the function we are applying as argument.
    
    2083
    -etaExpansionTick :: Id -> GenTickish pass -> Bool
    
    2084
    -etaExpansionTick id t
    
    2085
    -  = ( cantEtaReduceFun id ) &&
    
    2086
    -    ( tickishFloatable t || isProfTick t )
    
    2083
    +canCollectArgsThroughTick
    
    2084
    +  :: Id -- ^ function at the head of the application
    
    2085
    +  -> GenTickish pass -- ^ tick we want to collect arguments past
    
    2086
    +  -> Bool
    
    2087
    +canCollectArgsThroughTick id t
    
    2088
    +  =  tickishFloatable t
    
    2089
    +  || (cantEtaReduceFun id && isProfTick t)
    
    2087 2090
     
    
    2088 2091
     -- | Can we eta-reduce the given function?
    
    2089 2092
     -- See Note [Eta reduction soundness], criteria (B), (J), and (W).
    

  • compiler/GHC/CoreToStg/Prep.hs
    ... ... @@ -1052,8 +1052,8 @@ cpeApp top_env expr
    1052 1052
                 -- floating the tick which isn't optimal for perf. But this only makes
    
    1053 1053
                 -- a difference if we have a non-floatable tick which is somewhat rare.
    
    1054 1054
                 | Var vh <- head
    
    1055
    -            , Var head' <- lookupCorePrepEnv top_env vh
    
    1056
    -            , etaExpansionTick head' tickish
    
    1055
    +            , Just head' <- getIdFromTrivialExpr_maybe (lookupCorePrepEnv top_env vh)
    
    1056
    +            , canCollectArgsThroughTick head' tickish
    
    1057 1057
                 = (head,as')
    
    1058 1058
                 where
    
    1059 1059
                   (head,as') = go fun (AITick tickish : as)
    

  • compiler/GHC/Types/Basic.hs
    ... ... @@ -24,7 +24,7 @@ module GHC.Types.Basic (
    24 24
             ConTag, ConTagZ, fIRST_TAG,
    
    25 25
     
    
    26 26
             Arity, VisArity, RepArity, JoinArity, FullArgCount,
    
    27
    -        JoinPointHood(..), isJoinPoint,
    
    27
    +        JoinPointType(..), JoinPointHood(..), joinPointHoodArity, isJoinPoint,
    
    28 28
     
    
    29 29
             Alignment, mkAlignment, alignmentOf, alignmentBytes,
    
    30 30
     
    
    ... ... @@ -70,7 +70,7 @@ module GHC.Types.Basic (
    70 70
             BranchCount, oneBranch,
    
    71 71
             InterestingCxt(..),
    
    72 72
             TailCallInfo(..), tailCallInfo, zapOccTailCallInfo,
    
    73
    -        isAlwaysTailCalled, occInfoIsTrueJoinPoint,
    
    73
    +        isAlwaysTailCalled, occInfoJoinPointType_maybe,
    
    74 74
     
    
    75 75
             EP(..),
    
    76 76
     
    
    ... ... @@ -1150,11 +1150,16 @@ instance Monoid InsideLam where
    1150 1150
     
    
    1151 1151
     -----------------
    
    1152 1152
     
    
    1153
    +joinPointHoodArity :: JoinPointHood -> Maybe JoinArity
    
    1154
    +joinPointHoodArity = \case
    
    1155
    +  NotJoinPoint -> Nothing
    
    1156
    +  JoinPoint { joinPointArity = ja } -> Just ja
    
    1157
    +
    
    1153 1158
     -- | See Note [TailCallInfo]
    
    1154 1159
     data TailCallInfo
    
    1155 1160
       = AlwaysTailCalled
    
    1156
    -     { tailCallArity :: {-# UNPACK #-} !JoinArity
    
    1157
    -     , trueTailCall  :: !Bool -- ^ is this a true join point? see Note [Quasi join points]
    
    1161
    +     { tailCallArity         :: {-# UNPACK #-} !JoinArity
    
    1162
    +     , tailCallJoinPointType :: !JoinPointType -- ^ See Note [Quasi join points]
    
    1158 1163
          }
    
    1159 1164
       | NoTailCallInfo
    
    1160 1165
       deriving (Eq)
    
    ... ... @@ -1176,14 +1181,14 @@ isAlwaysTailCalled occ
    1176 1181
     -- If so, is it a true join point or a quasi join point?
    
    1177 1182
     --
    
    1178 1183
     -- See Note [Quasi join points] in GHC.Core.Opt.Simplify.Iteration.
    
    1179
    -occInfoIsTrueJoinPoint :: OccInfo -> Maybe Bool
    
    1180
    -occInfoIsTrueJoinPoint occ =
    
    1184
    +occInfoJoinPointType_maybe :: OccInfo -> Maybe JoinPointType
    
    1185
    +occInfoJoinPointType_maybe occ =
    
    1181 1186
       case tailCallInfo occ of
    
    1182
    -    AlwaysTailCalled { trueTailCall = true } -> Just true
    
    1187
    +    AlwaysTailCalled { tailCallJoinPointType = join_ty } -> Just join_ty
    
    1183 1188
         NoTailCallInfo -> Nothing
    
    1184 1189
     instance Outputable TailCallInfo where
    
    1185
    -  ppr (AlwaysTailCalled ar t) =
    
    1186
    -    sep [ text "Tail", (if t then empty else text "Quasi"), int ar ]
    
    1190
    +  ppr (AlwaysTailCalled { tailCallJoinPointType = join_ty, tailCallArity = ar }) =
    
    1191
    +    sep [ ppr join_ty <> text "Tail", int ar ]
    
    1187 1192
       ppr NoTailCallInfo = text "NoTailCallInfo"
    
    1188 1193
     
    
    1189 1194
     -----------------
    
    ... ... @@ -1232,8 +1237,11 @@ instance Outputable OccInfo where
    1232 1237
               pp_tail                = pprShortTailCallInfo tail_info
    
    1233 1238
     
    
    1234 1239
     pprShortTailCallInfo :: TailCallInfo -> SDoc
    
    1235
    -pprShortTailCallInfo (AlwaysTailCalled ar t)
    
    1236
    -  = char 'T' <> (if t then empty else text "[Q]")
    
    1240
    +pprShortTailCallInfo
    
    1241
    +  (AlwaysTailCalled
    
    1242
    +    { tailCallJoinPointType = join_type
    
    1243
    +    , tailCallArity = ar })
    
    1244
    +  = char 'T' <> (case join_type of { TrueJoinPoint -> empty; QuasiJoinPoint -> char 'Q' })
    
    1237 1245
                  <> brackets (int ar)
    
    1238 1246
     pprShortTailCallInfo NoTailCallInfo        = empty
    
    1239 1247
     
    

  • compiler/GHC/Types/Id.hs
    ... ... @@ -574,7 +574,7 @@ isWorkerLikeId id =
    574 574
     isJoinId :: Var -> Bool
    
    575 575
     isJoinId = isJust . joinId_maybe
    
    576 576
     
    
    577
    -joinId_maybe :: Var -> Maybe JoinType
    
    577
    +joinId_maybe :: Var -> Maybe JoinPointType
    
    578 578
     -- It is convenient in GHC.Core.Opt.SetLevels.lvlMFE to apply isJoinId
    
    579 579
     -- to the free vars of an expression, so it's convenient
    
    580 580
     -- if it returns False for type variables
    
    ... ... @@ -589,10 +589,11 @@ idJoinPointHood :: Var -> JoinPointHood
    589 589
     idJoinPointHood id
    
    590 590
      | isId id
    
    591 591
      = case Var.idDetails id of
    
    592
    -    JoinId ty arity _marks ->
    
    593
    -      let isTrue = case ty of { TrueJoinPoint -> True; QuasiJoinPoint -> False}
    
    594
    -      in JoinPoint isTrue arity
    
    595
    -    _                      -> NotJoinPoint
    
    592
    +    JoinId
    
    593
    +      { joinIdType  = join_type
    
    594
    +      , joinIdArity = arity }
    
    595
    +      -> JoinPoint join_type arity
    
    596
    +    _ -> NotJoinPoint
    
    596 597
      | otherwise = NotJoinPoint
    
    597 598
     
    
    598 599
     idDataCon :: Id -> DataCon
    
    ... ... @@ -675,7 +676,7 @@ idJoinArity id =
    675 676
         JoinPoint { joinPointArity = ar } -> ar
    
    676 677
         NotJoinPoint -> pprPanic "idJoinArity" (ppr id)
    
    677 678
     
    
    678
    -asJoinId :: Id -> JoinType -> JoinArity -> JoinId
    
    679
    +asJoinId :: Id -> JoinPointType -> JoinArity -> JoinId
    
    679 680
     asJoinId id ty arity
    
    680 681
       = warnPprTrace (not (isLocalId id))
    
    681 682
           "global id being marked as join var"  (ppr id) $
    
    ... ... @@ -710,9 +711,8 @@ zapJoinId jid
    710 711
     asJoinId_maybe :: Id -> JoinPointHood -> Id
    
    711 712
     asJoinId_maybe id = \case
    
    712 713
       NotJoinPoint -> zapJoinId id
    
    713
    -  JoinPoint { isTrueJoinPoint = true_join, joinPointArity = arity } ->
    
    714
    -    let ty = if true_join then TrueJoinPoint else QuasiJoinPoint
    
    715
    -    in asJoinId id ty arity
    
    714
    +  JoinPoint { joinPointType = join_type, joinPointArity = arity } ->
    
    715
    +    asJoinId id join_type arity
    
    716 716
     
    
    717 717
     {-
    
    718 718
     ************************************************************************
    

  • compiler/GHC/Types/Id/Info.hs
    ... ... @@ -65,7 +65,7 @@ module GHC.Types.Id.Info (
    65 65
             TailCallInfo(..),
    
    66 66
             tailCallInfo, isAlwaysTailCalled,
    
    67 67
     
    
    68
    -        JoinType(..),
    
    68
    +        JoinPointType(..),
    
    69 69
     
    
    70 70
             -- ** The RuleInfo type
    
    71 71
             RuleInfo(..),
    
    ... ... @@ -207,7 +207,7 @@ data IdDetails
    207 207
                    -- This only covers /un-lifted/ coercions, of type
    
    208 208
                    -- (t1 ~# t2) or (t1 ~R# t2), not their lifted variants
    
    209 209
       | JoinId
    
    210
    -      { joinIdType :: JoinType
    
    210
    +      { joinIdType :: JoinPointType
    
    211 211
           , joinIdArity :: JoinArity
    
    212 212
           , joinIdCbvMarks :: Maybe [CbvMark]
    
    213 213
           }
    
    ... ... @@ -226,14 +226,6 @@ data IdDetails
    226 226
             -- The [CbvMark] is always empty (and ignored) until after Tidy for ids from the current
    
    227 227
             -- module.
    
    228 228
     
    
    229
    -data JoinType
    
    230
    -  = TrueJoinPoint
    
    231
    -  | QuasiJoinPoint
    
    232
    -  deriving stock ( Eq, Show )
    
    233
    -instance Outputable JoinType where
    
    234
    -  ppr TrueJoinPoint  = text "TrueJoinPoint"
    
    235
    -  ppr QuasiJoinPoint = text "QuasiJoinPoint"
    
    236
    -
    
    237 229
     data RecSelInfo
    
    238 230
       = RSI { rsi_def   :: [ConLike]   -- Record selector defined for these
    
    239 231
             , rsi_undef :: [ConLike]   -- Record selector not defined for these
    
    ... ... @@ -422,7 +414,7 @@ isCoVarDetails :: IdDetails -> Bool
    422 414
     isCoVarDetails CoVarId = True
    
    423 415
     isCoVarDetails _       = False
    
    424 416
     
    
    425
    -isJoinIdDetails_maybe :: IdDetails -> Maybe (JoinType, JoinArity, Maybe [CbvMark])
    
    417
    +isJoinIdDetails_maybe :: IdDetails -> Maybe (JoinPointType, JoinArity, Maybe [CbvMark])
    
    426 418
     isJoinIdDetails_maybe (JoinId ty join_arity marks) = Just (ty, join_arity, marks)
    
    427 419
     isJoinIdDetails_maybe _                            = Nothing
    
    428 420
     
    

  • compiler/GHC/Types/Tickish.hs
    ... ... @@ -330,7 +330,8 @@ tickishCanSplit _ = False
    330 330
     -- | Is @join f x in <tick> jump f x@ valid?
    
    331 331
     tickishCanScopeJoin :: GenTickish pass -> Bool
    
    332 332
     tickishCanScopeJoin tick = case tick of
    
    333
    -  ProfNote{} -> True
    
    333
    +  ProfNote{} -> False -- Turns the join point into a quasi join point.
    
    334
    +                      -- See Note [Quasi join points]
    
    334 335
       HpcTick{} -> False
    
    335 336
       Breakpoint{} -> False
    
    336 337
       SourceNote{} -> True
    

  • compiler/GHC/Utils/Binary.hs
    ... ... @@ -132,7 +132,7 @@ import GHC.Utils.Fingerprint
    132 132
     import GHC.Types.SrcLoc
    
    133 133
     import GHC.Types.Unique
    
    134 134
     import qualified GHC.Data.Strict as Strict
    
    135
    -import GHC.Utils.Outputable( JoinPointHood(..) )
    
    135
    +import GHC.Utils.Outputable( JoinPointHood(..), JoinPointType (..) )
    
    136 136
     import GHCi.FFI
    
    137 137
     import GHCi.Message
    
    138 138
     
    
    ... ... @@ -1053,6 +1053,10 @@ instance Binary DiffTime where
    1053 1053
         get bh = do r <- get bh
    
    1054 1054
                     return $ fromRational r
    
    1055 1055
     
    
    1056
    +instance Binary JoinPointType where
    
    1057
    +  put_ bh ty = put_ bh (ty == TrueJoinPoint)
    
    1058
    +  get bh = do { true <- get bh; return $ if true then TrueJoinPoint else QuasiJoinPoint }
    
    1059
    +
    
    1056 1060
     instance Binary JoinPointHood where
    
    1057 1061
         put_ bh NotJoinPoint = putByte bh 0
    
    1058 1062
         put_ bh (JoinPoint t ar) = do
    

  • compiler/GHC/Utils/Outputable.hs
    ... ... @@ -15,7 +15,7 @@
    15 15
     module GHC.Utils.Outputable (
    
    16 16
             -- * Type classes
    
    17 17
             Outputable(..), OutputableBndr(..), OutputableP(..),
    
    18
    -        BindingSite(..),  JoinPointHood(..), isJoinPoint,
    
    18
    +        BindingSite(..), JoinPointType(..), JoinPointHood(..), isJoinPoint,
    
    19 19
     
    
    20 20
             IsOutput(..), IsLine(..), IsDoc(..),
    
    21 21
             HLine, HDoc,
    
    ... ... @@ -150,6 +150,7 @@ import Data.Graph (SCC(..))
    150 150
     import Data.List (intersperse)
    
    151 151
     import Data.List.NonEmpty (NonEmpty (..))
    
    152 152
     import Data.Semigroup (Arg(..))
    
    153
    +import qualified Data.Semigroup as Semi
    
    153 154
     import qualified Data.List.NonEmpty as NEL
    
    154 155
     import Data.Time ( UTCTime )
    
    155 156
     import Data.Time.Format.ISO8601
    
    ... ... @@ -1284,10 +1285,21 @@ data BindingSite
    1284 1285
         | LetBind     -- ^ The x in   (let x = rhs in e)
    
    1285 1286
         deriving Eq
    
    1286 1287
     
    
    1288
    +data JoinPointType
    
    1289
    +  = TrueJoinPoint
    
    1290
    +  | QuasiJoinPoint
    
    1291
    +  deriving Eq
    
    1292
    +instance Outputable JoinPointType where
    
    1293
    +  ppr TrueJoinPoint = empty
    
    1294
    +  ppr QuasiJoinPoint = text "Quasi"
    
    1295
    +instance Semigroup JoinPointType where
    
    1296
    +  TrueJoinPoint <> TrueJoinPoint = TrueJoinPoint
    
    1297
    +  _ <> _ = QuasiJoinPoint
    
    1298
    +
    
    1287 1299
     data JoinPointHood
    
    1288 1300
       = JoinPoint
    
    1289
    -      { isTrueJoinPoint :: {-# UNPACK #-} !Bool
    
    1290
    -      , joinPointArity  :: {-# UNPACK #-} !Int
    
    1301
    +      { joinPointType  :: {-# UNPACK #-} !JoinPointType
    
    1302
    +      , joinPointArity :: {-# UNPACK #-} !Int
    
    1291 1303
             -- ^ The JoinArity (but an Int here because synonym JoinArity is defined in Types.Basic)
    
    1292 1304
           }
    
    1293 1305
       | NotJoinPoint
    
    ... ... @@ -1298,10 +1310,9 @@ isJoinPoint (JoinPoint {}) = True
    1298 1310
     isJoinPoint NotJoinPoint   = False
    
    1299 1311
     
    
    1300 1312
     instance Outputable JoinPointHood where
    
    1301
    -  ppr NotJoinPoint           = text "NotJoinPoint"
    
    1302
    -  ppr (JoinPoint true arity) =
    
    1303
    -       (if true then empty else text "Quasi")
    
    1304
    -    <> text "JoinPoint" <> parens (ppr arity)
    
    1313
    +  ppr NotJoinPoint = text "NotJoinPoint"
    
    1314
    +  ppr (JoinPoint join_type arity) =
    
    1315
    +    ppr join_type <> text "JoinPoint" <> parens (ppr arity)
    
    1305 1316
     
    
    1306 1317
     instance NFData JoinPointHood where
    
    1307 1318
       rnf x = x `seq` ()