Zubin pushed to branch wip/26416 at Glasgow Haskell Compiler / GHC

Commits:

2 changed files:

Changes:

  • compiler/GHC/Core/Opt/DmdAnal.hs
    ... ... @@ -1105,19 +1105,13 @@ dmdAnalRhsSig top_lvl rec_flag env let_sd id rhs
    1105 1105
         rhs_sd = mkCalledOnceDmds ww_arity adjusted_body_sd
    
    1106 1106
     
    
    1107 1107
         WithDmdType rhs_dmd_ty rhs' = dmdAnal env rhs_sd rhs
    
    1108
    -    DmdType rhs_env rhs_dmds = rhs_dmd_ty
    
    1109 1108
     
    
    1110
    -    -- See Note [Absence analysis for stable unfoldings and RULES]
    
    1111
    -    -- If there's a stable unfolding, we need to combine argument demands
    
    1112
    -    -- from the unfolding with those from the RHS, because the unfolding
    
    1113
    -    -- might use arguments that the (optimised) RHS doesn't.
    
    1114
    -    -- Any argument with a demand absent in one but not the other can
    
    1115
    -    -- be problematic, see #26416
    
    1116
    -    -- Also combine the DmdEnv (free variables) from the unfolding
    
    1117
    -    (unf_fv_env, combined_rhs_dmds) = combineUnfoldingDmds env rhs_sd id rhs_env rhs_dmds
    
    1109
    +    -- See Note [Absence analysis for stable unfoldings and RULES], Wrinkle (W3)
    
    1110
    +    full_dmd_ty = addUnfoldingDemands env rhs_sd id rhs_dmd_ty
    
    1111
    +    DmdType full_rhs_env combined_rhs_dmds = full_dmd_ty
    
    1118 1112
     
    
    1119 1113
         (final_rhs_dmds, final_rhs) = finaliseArgBoxities env id ww_arity
    
    1120
    -                                                      combined_rhs_dmds (de_div rhs_env) rhs'
    
    1114
    +                                                      combined_rhs_dmds (de_div full_rhs_env) rhs'
    
    1121 1115
     
    
    1122 1116
         dmd_sig_arity = ww_arity + strictCallArity body_sd
    
    1123 1117
         sig = mkDmdSigForArity dmd_sig_arity (DmdType sig_env final_rhs_dmds)
    
    ... ... @@ -1141,14 +1135,13 @@ dmdAnalRhsSig top_lvl rec_flag env let_sd id rhs
    1141 1135
         --        we never get used-once info for FVs of recursive functions.
    
    1142 1136
         --        See #14816 where we try to get rid of reuseEnv.
    
    1143 1137
         rhs_env1 = case rec_flag of
    
    1144
    -                Recursive    -> reuseEnv rhs_env
    
    1145
    -                NonRecursive -> rhs_env
    
    1138
    +                Recursive    -> reuseEnv full_rhs_env
    
    1139
    +                NonRecursive -> full_rhs_env
    
    1146 1140
     
    
    1147 1141
         -- See Note [Absence analysis for stable unfoldings and RULES]
    
    1148
    -    -- The unfolding FVs are handled via unf_fv_env from combineUnfoldingDmds.
    
    1142
    +    -- The unfolding FVs are already included in full_rhs_env via addUnfoldingDemands.
    
    1149 1143
         -- Here we only need demandRoots for RULES.
    
    1150
    -    rhs_env2 = rhs_env1 `plusDmdEnv` unf_fv_env
    
    1151
    -                        `plusDmdEnv` demandRootSet env (idRuleVars id)
    
    1144
    +    rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (idRuleVars id)
    
    1152 1145
     
    
    1153 1146
         -- See Note [Lazy and unleashable free variables]
    
    1154 1147
         !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2
    
    ... ... @@ -1160,27 +1153,19 @@ splitWeakDmds (DE fvs div) = (DE sig_fvs div, weak_fvs)
    1160 1153
     -- | If there is a stable unfolding, combine argument demands and free variable
    
    1161 1154
     -- demands from the unfolding with those from the RHS.
    
    1162 1155
     -- See Note [Absence analysis for stable unfoldings and RULES], Wrinkle (W3).
    
    1163
    ---
    
    1164
    --- Returns (combined DmdEnv for free variables, combined arg demands)
    
    1165
    --- The DmdEnv is nopDmdEnv if there's no stable unfolding.
    
    1166
    -combineUnfoldingDmds :: AnalEnv -> SubDemand -> Id -> DmdEnv -> [Demand] -> (DmdEnv, [Demand])
    
    1167
    -combineUnfoldingDmds env rhs_sd id rhs_fv_env rhs_dmds
    
    1168
    -  | not (isStableUnfolding unf)
    
    1169
    -  = (nopDmdEnv, rhs_dmds)  -- No stable unfolding, nothing to do
    
    1170
    -
    
    1171
    -  | Just unf_body <- maybeUnfoldingTemplate unf
    
    1172
    -  , let WithDmdType (DmdType unf_fv_env unf_dmds) _ = dmdAnal env rhs_sd unf_body
    
    1173
    -  , let combined_dmds = go rhs_dmds unf_dmds
    
    1174
    -        -- Lub the free variable demands from unfolding with RHS
    
    1175
    -        combined_fv_env = lubDmdEnv rhs_fv_env unf_fv_env
    
    1176
    -  = -- pprTrace "combineUnfoldingDmds" (ppr id $$ ppr rhs_dmds $$ ppr unf_dmds $$ ppr combined_dmds) $
    
    1177
    -   (combined_fv_env, combined_dmds)
    
    1178
    -  | otherwise = (nopDmdEnv, rhs_dmds)
    
    1156
    +-- See Note [Combining demands for stable unfoldings] in GHC.Types.Demand.
    
    1157
    +addUnfoldingDemands :: AnalEnv -> SubDemand -> Id -> DmdType -> DmdType
    
    1158
    +addUnfoldingDemands env rhs_sd id rhs_dmd_ty
    
    1159
    +  | isStableUnfolding unf
    
    1160
    +  , Just unf_body <- maybeUnfoldingTemplate unf
    
    1161
    +  , let WithDmdType unf_dmd_ty _ = dmdAnal env rhs_sd unf_body
    
    1162
    +  = -- pprTrace "addUnfoldingDemands" (ppr id $$ ppr rhs_dmd_ty $$ ppr unf_dmd_ty) $
    
    1163
    +    lubUBglbLBDmdType rhs_dmd_ty unf_dmd_ty
    
    1164
    +
    
    1165
    +  | otherwise
    
    1166
    +  = rhs_dmd_ty  -- No stable unfolding, nothing to do
    
    1179 1167
       where
    
    1180 1168
         unf = realIdUnfolding id
    
    1181
    -    go rhs          []            = rhs
    
    1182
    -    go []           _             = []
    
    1183
    -    go (r:rhs)      (u:unfs)      = lubUBglbLBDmd r u : go rhs unfs
    
    1184 1169
     
    
    1185 1170
     -- | The result type after applying 'idArity' many arguments. Returns 'Nothing'
    
    1186 1171
     -- when the type doesn't have exactly 'idArity' many arrows.
    
    ... ... @@ -1577,17 +1562,13 @@ Wrinkles:
    1577 1562
     
    
    1578 1563
         SOLUTION: in `dmdAnalRhsSig`, if the function has a stable unfolding,
    
    1579 1564
         analyse it with `dmdAnal` and combine the resulting `DmdType` with the
    
    1580
    -    RHS's `DmdType`. This is done by `combineUnfoldingDmds`, which:
    
    1581
    -
    
    1582
    -      * For argument demands: combines them using `lubUBglbLBDmd`, which takes
    
    1583
    -        the glb (max) of lower bounds (strictness) and lub (max) of upper
    
    1584
    -        bounds (usage). See Note [Combining demands for stable unfoldings].
    
    1585
    -        This ensures that if the unfolding uses an argument, it won't be
    
    1586
    -        marked as absent, while preserving any strictness the RHS reveals.
    
    1565
    +    RHS's `DmdType`. This is done by `addUnfoldingDemands`, which uses
    
    1566
    +    `lubUBglbLBDmdType` to combine both argument demands and free variable
    
    1567
    +    demands. See Note [Combining demands for stable unfoldings] in
    
    1568
    +    GHC.Types.Demand for details of the combining operation.
    
    1587 1569
     
    
    1588
    -      * For free variable demands: combines them using `lubDmdEnv`. This
    
    1589
    -        replaces the `demandRoots` approach for stable unfoldings (though
    
    1590
    -        we still use `demandRoots` for RULES via `idRuleVars`).
    
    1570
    +    This replaces the `demandRoots` approach for stable unfoldings (though
    
    1571
    +    we still use `demandRoots` for RULES via `idRuleVars`).
    
    1591 1572
     
    
    1592 1573
     Note [DmdAnal for DataCon wrappers]
    
    1593 1574
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/Types/Demand.hs
    ... ... @@ -57,7 +57,7 @@ module GHC.Types.Demand (
    57 57
         DmdType(..), dmdTypeDepth,
    
    58 58
         -- ** Algebra
    
    59 59
         nopDmdType, botDmdType,
    
    60
    -    lubDmdType, plusDmdType, multDmdType, discardArgDmds,
    
    60
    +    lubDmdType, lubUBglbLBDmdType, plusDmdType, multDmdType, discardArgDmds,
    
    61 61
         -- ** Other operations
    
    62 62
         peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException,
    
    63 63
     
    
    ... ... @@ -1907,6 +1907,26 @@ lubDmdType d1 d2 = DmdType lub_fv lub_ds
    1907 1907
         lub_ds  = zipWithEqual lubDmd ds1 ds2
    
    1908 1908
         lub_fv = lubDmdEnv fv1 fv2
    
    1909 1909
     
    
    1910
    +-- | Combine two 'DmdType's for stable unfolding analysis.
    
    1911
    +-- See Note [Combining demands for stable unfoldings].
    
    1912
    +lubUBglbLBDmdType :: DmdType -> DmdType -> DmdType
    
    1913
    +lubUBglbLBDmdType (DmdType fv1 ds1) (DmdType fv2 ds2)
    
    1914
    +  = DmdType combined_fv combined_ds
    
    1915
    +  where
    
    1916
    +    combined_fv = lubUBglbLBDmdEnv fv1 fv2
    
    1917
    +    combined_ds = go ds1 ds2
    
    1918
    +    -- If lists have different lengths, keep remaining ds1 (from RHS)
    
    1919
    +    go rhs []           = rhs
    
    1920
    +    go []  _            = []
    
    1921
    +    go (r:rhs) (u:unfs) = lubUBglbLBDmd r u : go rhs unfs
    
    1922
    +
    
    1923
    +-- | See Note [Combining demands for stable unfoldings].
    
    1924
    +lubUBglbLBDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv
    
    1925
    +lubUBglbLBDmdEnv (DE fv1 d1) (DE fv2 d2) = DE combined_fv combined_div
    
    1926
    +  where
    
    1927
    +    combined_fv  = plusVarEnv_CD lubUBglbLBDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)
    
    1928
    +    combined_div = lubDivergence d1 d2
    
    1929
    +
    
    1910 1930
     discardArgDmds :: DmdType -> DmdEnv
    
    1911 1931
     discardArgDmds (DmdType fv _) = fv
    
    1912 1932