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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/Opt/DmdAnal.hs
    ... ... @@ -1141,7 +1141,7 @@ dmdAnalRhsSig top_lvl rec_flag env let_sd id rhs
    1141 1141
         -- See Note [Absence analysis for stable unfoldings and RULES]
    
    1142 1142
         -- The unfolding FVs are already included in full_rhs_env via addUnfoldingDemands.
    
    1143 1143
         -- Here we only need demandRoots for RULES.
    
    1144
    -    rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (idRuleVars id)
    
    1144
    +    rhs_env2 = rhs_env1 `plusDmdEnv` demandRootSet env (filterVarSet isId (idRuleVars id))
    
    1145 1145
     
    
    1146 1146
         -- See Note [Lazy and unleashable free variables]
    
    1147 1147
         !(!sig_env, !weak_fvs) = splitWeakDmds rhs_env2
    
    ... ... @@ -1160,7 +1160,7 @@ addUnfoldingDemands env rhs_sd id rhs_dmd_ty
    1160 1160
       , Just unf_body <- maybeUnfoldingTemplate unf
    
    1161 1161
       , let WithDmdType unf_dmd_ty _ = dmdAnal env rhs_sd unf_body
    
    1162 1162
       = -- pprTrace "addUnfoldingDemands" (ppr id $$ ppr rhs_dmd_ty $$ ppr unf_dmd_ty) $
    
    1163
    -    lubUBglbLBDmdType rhs_dmd_ty unf_dmd_ty
    
    1163
    +    maxDmdType rhs_dmd_ty unf_dmd_ty
    
    1164 1164
     
    
    1165 1165
       | otherwise
    
    1166 1166
       = rhs_dmd_ty  -- No stable unfolding, nothing to do
    
    ... ... @@ -1504,10 +1504,21 @@ and transform to
    1504 1504
     
    
    1505 1505
     Now if f is subsequently inlined, we'll use 'g' and ... disaster.
    
    1506 1506
     
    
    1507
    -SOLUTION: if f has a stable unfolding, treat every free variable as a
    
    1508
    -/demand root/, that is: Analyse it as if it was a variable occurring in a
    
    1507
    +SOLUTION for stable unfoldings: in `dmdAnalRhsSig`, if the function has a
    
    1508
    +stable unfolding, analyse it with `dmdAnal` and combine the resulting `DmdType`
    
    1509
    +with the RHS's `DmdType`. This is done by `addUnfoldingDemands`, which uses
    
    1510
    +`maxDmdType` to combine both argument demands and free variable demands.
    
    1511
    +See Note [Combining demands for stable unfoldings] in GHC.Types.Demand for
    
    1512
    +details of the combining operation.
    
    1513
    +
    
    1514
    +This handles both the free variables and arguments of stable unfoldings in one
    
    1515
    +go. For example, in the scenario above, the unfolding's `DmdType` will mention
    
    1516
    +`g` as a free variable, so `maxDmdType` will keep it alive.
    
    1517
    +
    
    1518
    +SOLUTION for RULES: treat every Id free in the RHS of a RULE as a
    
    1519
    +/demand root/, that is: analyse it as if it was a variable occurring in a
    
    1509 1520
     'topDmd' context. This is done in `demandRoot` (which we also use for exported
    
    1510
    -top-level ids). Do the same for Ids free in the RHS of any RULES for f.
    
    1521
    +top-level ids).
    
    1511 1522
     
    
    1512 1523
     Wrinkles:
    
    1513 1524
     
    
    ... ... @@ -1524,7 +1535,7 @@ Wrinkles:
    1524 1535
         this, that actually happened in practice.
    
    1525 1536
     
    
    1526 1537
       (W2) You might wonder why we don't simply take the free vars of the
    
    1527
    -    unfolding/RULE and map them to topDmd. The reason is that any of the free vars
    
    1538
    +    RULE and map them to topDmd. The reason is that any of the free vars
    
    1528 1539
         might have demand signatures themselves that in turn demand transitive free
    
    1529 1540
         variables and that we hence need to unleash! This came up in #23208.
    
    1530 1541
         Consider
    
    ... ... @@ -1546,7 +1557,7 @@ Wrinkles:
    1546 1557
         for `sg`, failing to unleash the signature and hence observed an absent
    
    1547 1558
         error instead of the `really important message`.
    
    1548 1559
     
    
    1549
    -  (W3) The SOLUTION above handles /free variables/ of stable unfoldings, but
    
    1560
    +  (W3) The stable unfolding solution above handles /free variables/, but
    
    1550 1561
         what about /arguments/?  Consider (#26416)
    
    1551 1562
     
    
    1552 1563
            fromVector :: (Storable a, KnownNat n) => Vector a -> Vector a
    
    ... ... @@ -1560,15 +1571,9 @@ Wrinkles:
    1560 1571
         worker's unfolding is inlined, it will use that rubbish value as a real
    
    1561 1572
         dictionary, leading to a segfault!
    
    1562 1573
     
    
    1563
    -    SOLUTION: in `dmdAnalRhsSig`, if the function has a stable unfolding,
    
    1564
    -    analyse it with `dmdAnal` and combine the resulting `DmdType` with the
    
    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.
    
    1569
    -
    
    1570
    -    This replaces the `demandRoots` approach for stable unfoldings (though
    
    1571
    -    we still use `demandRoots` for RULES via `idRuleVars`).
    
    1574
    +    `addUnfoldingDemands` handles this too: since `maxDmdType` combines both
    
    1575
    +    the argument demands and free variable demands from the unfolding's
    
    1576
    +    `DmdType` with the RHS's, argument absence is correctly prevented.
    
    1572 1577
     
    
    1573 1578
     Note [DmdAnal for DataCon wrappers]
    
    1574 1579
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -2052,8 +2057,15 @@ finaliseArgBoxities :: AnalEnv -> Id -> Arity
    2052 2057
     -- If:    (dmds', rhs') = finaliseArgBoxitities ... dmds .. rhs
    
    2053 2058
     -- Then:
    
    2054 2059
     --     dmds' is the same as dmds (including length), except for boxity info
    
    2055
    ---     rhs'  is the same as rhs, except for dmd info on lambda binders
    
    2060
    +--     rhs'  is the same as rhs, except that the idDemandInfo on the outer
    
    2061
    +--           lambda binders now includes the same finalised boxity info as dmds'
    
    2056 2062
     -- NB: For join points, length dmds might be greater than ww_arity
    
    2063
    +--
    
    2064
    +-- IMPORTANT: The lambda binders of rhs' must carry the final demand info,
    
    2065
    +-- because worker/wrapper drives decisions from the idDemandInfo on the lambdas
    
    2066
    +-- (see mkWwstr_one), NOT from the strictness signature of the function.
    
    2067
    +-- So the demands must reflect both the unfolding combination (from
    
    2068
    +-- addUnfoldingDemands) and the boxity finalisation done here.
    
    2057 2069
     finaliseArgBoxities env fn ww_arity arg_dmds div rhs
    
    2058 2070
     
    
    2059 2071
       -- Check for an OPAQUE function: see Note [OPAQUE pragma]
    
    ... ... @@ -2097,7 +2109,7 @@ finaliseArgBoxities env fn ww_arity arg_dmds div rhs
    2097 2109
                               [ bndr | bndr <- bndrs, isRuntimeVar bndr ]
    
    2098 2110
                               arg_dmds
    
    2099 2111
           where
    
    2100
    -        mk_triple bndr dmd = (idType bndr, NotMarkedStrict, get_dmd dmd)
    
    2112
    +        mk_triple bndr arg_dmd = (idType bndr, NotMarkedStrict, get_dmd arg_dmd)
    
    2101 2113
     
    
    2102 2114
         arg_dmds' = ww_arg_dmds ++ map trimBoxity (drop ww_arity arg_dmds)
    
    2103 2115
                     -- If ww_arity < length arg_dmds, the leftover ones
    

  • compiler/GHC/Types/Demand.hs
    ... ... @@ -23,8 +23,8 @@ module GHC.Types.Demand (
    23 23
         lubCard, lubDmd, lubSubDmd,
    
    24 24
         -- *** Greatest lower bound
    
    25 25
         glbCard,
    
    26
    -    -- *** Unfolding combination (glb on strictness, lub on usage)
    
    27
    -    lubUBglbLBDmd,
    
    26
    +    -- *** Maximum (glb on strictness, lub on usage)
    
    27
    +    maxCard, maxDmd,
    
    28 28
         -- *** Plus
    
    29 29
         plusCard, plusDmd, plusSubDmd,
    
    30 30
         -- *** Multiply
    
    ... ... @@ -57,7 +57,7 @@ module GHC.Types.Demand (
    57 57
         DmdType(..), dmdTypeDepth,
    
    58 58
         -- ** Algebra
    
    59 59
         nopDmdType, botDmdType,
    
    60
    -    lubDmdType, lubUBglbLBDmdType, plusDmdType, multDmdType, discardArgDmds,
    
    60
    +    lubDmdType, maxDmdType, plusDmdType, multDmdType, discardArgDmds,
    
    61 61
         -- ** Other operations
    
    62 62
         peelFV, findIdDemand, addDemand, splitDmdTy, deferAfterPreciseException,
    
    63 63
     
    
    ... ... @@ -899,43 +899,46 @@ See Note [Absence analysis for stable unfoldings and RULES] in GHC.Core.Opt.DmdA
    899 899
     for the broader context.
    
    900 900
     -}
    
    901 901
     
    
    902
    --- | Combine demands for stable unfolding analysis.
    
    902
    +-- | Takes the maximum of both the lower and upper bound of two 'Card's.
    
    903
    +-- Semantically, this is glb on lower (strictness) and lub on upper (usage).
    
    903 904
     -- See Note [Combining demands for stable unfoldings].
    
    904
    -lubUBglbLBCard :: Card -> Card -> Card
    
    905
    +maxCard :: Card -> Card -> Card
    
    905 906
     -- Given Note [Bit vector representation for Card]:
    
    906 907
     --   * bit 0 (strictness): take AND (glb) - 0 means strict, so 0 wins
    
    907 908
     --   * bits 1,2 (usage): take OR (lub) - if either uses, result uses
    
    908
    -lubUBglbLBCard (Card a) (Card b) = Card ((a .&. b .&. 0b001) .|. ((a .|. b) .&. 0b110))
    
    909
    +maxCard (Card a) (Card b) = Card ((a .&. b .&. 0b001) .|. ((a .|. b) .&. 0b110))
    
    909 910
     
    
    910
    --- | See Note [Combining demands for stable unfoldings].
    
    911
    -lubUBglbLBDmd :: Demand -> Demand -> Demand
    
    912
    -lubUBglbLBDmd BotDmd      dmd2        = dmd2
    
    913
    -lubUBglbLBDmd dmd1        BotDmd      = dmd1
    
    914
    -lubUBglbLBDmd (n1 :* sd1) (n2 :* sd2) =
    
    915
    -  lubUBglbLBCard n1 n2 :* lubUBglbLBSubDmd sd1 sd2
    
    911
    +-- | Takes the maximum of both the lower and upper bounds of two 'Demand's.
    
    912
    +-- Semantically, glb on lower (strictness) and lub on upper (usage).
    
    913
    +-- See Note [Combining demands for stable unfoldings].
    
    914
    +maxDmd :: Demand -> Demand -> Demand
    
    915
    +maxDmd BotDmd      dmd2        = dmd2
    
    916
    +maxDmd dmd1        BotDmd      = dmd1
    
    917
    +maxDmd (n1 :* sd1) (n2 :* sd2) =
    
    918
    +  maxCard n1 n2 :* maxSubDmd sd1 sd2
    
    916 919
     
    
    917
    -lubUBglbLBSubDmd :: SubDemand -> SubDemand -> SubDemand
    
    920
    +maxSubDmd :: SubDemand -> SubDemand -> SubDemand
    
    918 921
     -- Shortcuts for neutral and absorbing elements.
    
    919
    -lubUBglbLBSubDmd (Poly Unboxed C_10)  sd                   = sd
    
    920
    -lubUBglbLBSubDmd sd                   (Poly Unboxed C_10)  = sd
    
    921
    -lubUBglbLBSubDmd sd@(Poly Boxed C_0N) _                    = sd
    
    922
    -lubUBglbLBSubDmd _                    sd@(Poly Boxed C_0N) = sd
    
    922
    +maxSubDmd (Poly Unboxed C_00)  sd                   = sd
    
    923
    +maxSubDmd sd                   (Poly Unboxed C_00)  = sd
    
    924
    +maxSubDmd sd@(Poly Boxed C_1N) _                    = sd
    
    925
    +maxSubDmd _                    sd@(Poly Boxed C_1N) = sd
    
    923 926
     -- Prod
    
    924
    -lubUBglbLBSubDmd (Prod b1 ds1) (Poly b2 n2)
    
    927
    +maxSubDmd (Prod b1 ds1) (Poly b2 n2)
    
    925 928
       | let !d = polyFieldDmd b2 n2
    
    926
    -  = mkProd (lubBoxity b1 b2) (strictMap (lubUBglbLBDmd d) ds1)
    
    927
    -lubUBglbLBSubDmd (Prod b1 ds1) (Prod b2 ds2)
    
    929
    +  = mkProd (lubBoxity b1 b2) (strictMap (maxDmd d) ds1)
    
    930
    +maxSubDmd (Prod b1 ds1) (Prod b2 ds2)
    
    928 931
       | equalLength ds1 ds2
    
    929
    -  = mkProd (lubBoxity b1 b2) (strictZipWith lubUBglbLBDmd ds1 ds2)
    
    932
    +  = mkProd (lubBoxity b1 b2) (strictZipWith maxDmd ds1 ds2)
    
    930 933
     -- Handle Call
    
    931
    -lubUBglbLBSubDmd (Call n1 sd1) (viewCall -> Just (n2, sd2)) =
    
    932
    -  mkCall (lubUBglbLBCard n1 n2) (lubUBglbLBSubDmd sd1 sd2)
    
    934
    +maxSubDmd (Call n1 sd1) (viewCall -> Just (n2, sd2)) =
    
    935
    +  mkCall (maxCard n1 n2) (maxSubDmd sd1 sd2)
    
    933 936
     -- Handle Poly
    
    934
    -lubUBglbLBSubDmd (Poly b1 n1) (Poly b2 n2) = Poly (lubBoxity b1 b2) (lubUBglbLBCard n1 n2)
    
    937
    +maxSubDmd (Poly b1 n1) (Poly b2 n2) = Poly (lubBoxity b1 b2) (maxCard n1 n2)
    
    935 938
     -- Other Poly case by commutativity
    
    936
    -lubUBglbLBSubDmd sd1@Poly{}   sd2          = lubUBglbLBSubDmd sd2 sd1
    
    937
    --- Otherwise (Call `lubUBglbLB` Prod) return Top
    
    938
    -lubUBglbLBSubDmd _            _            = topSubDmd
    
    939
    +maxSubDmd sd1@Poly{}   sd2          = maxSubDmd sd2 sd1
    
    940
    +-- Otherwise (Call `max` Prod) return Top
    
    941
    +maxSubDmd _            _            = topSubDmd
    
    939 942
     
    
    940 943
     -- | Denotes '+' on 'Demand'.
    
    941 944
     plusDmd :: Demand -> Demand -> Demand
    
    ... ... @@ -1909,22 +1912,22 @@ lubDmdType d1 d2 = DmdType lub_fv lub_ds
    1909 1912
     
    
    1910 1913
     -- | Combine two 'DmdType's for stable unfolding analysis.
    
    1911 1914
     -- See Note [Combining demands for stable unfoldings].
    
    1912
    -lubUBglbLBDmdType :: DmdType -> DmdType -> DmdType
    
    1913
    -lubUBglbLBDmdType (DmdType fv1 ds1) (DmdType fv2 ds2)
    
    1915
    +maxDmdType :: DmdType -> DmdType -> DmdType
    
    1916
    +maxDmdType (DmdType fv1 ds1) (DmdType fv2 ds2)
    
    1914 1917
       = DmdType combined_fv combined_ds
    
    1915 1918
       where
    
    1916
    -    combined_fv = lubUBglbLBDmdEnv fv1 fv2
    
    1919
    +    combined_fv = maxDmdEnv fv1 fv2
    
    1917 1920
         combined_ds = go ds1 ds2
    
    1918 1921
         -- If lists have different lengths, keep remaining ds1 (from RHS)
    
    1919 1922
         go rhs []           = rhs
    
    1920 1923
         go []  _            = []
    
    1921
    -    go (r:rhs) (u:unfs) = lubUBglbLBDmd r u : go rhs unfs
    
    1924
    +    go (r:rhs) (u:unfs) = maxDmd r u : go rhs unfs
    
    1922 1925
     
    
    1923 1926
     -- | 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
    
    1927
    +maxDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv
    
    1928
    +maxDmdEnv (DE fv1 d1) (DE fv2 d2) = DE combined_fv combined_div
    
    1926 1929
       where
    
    1927
    -    combined_fv  = plusVarEnv_CD lubUBglbLBDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)
    
    1930
    +    combined_fv  = plusVarEnv_CD maxDmd fv1 (defaultFvDmd d1) fv2 (defaultFvDmd d2)
    
    1928 1931
         combined_div = lubDivergence d1 d2
    
    1929 1932
     
    
    1930 1933
     discardArgDmds :: DmdType -> DmdEnv
    

  • testsuite/tests/dmdanal/should_run/T26416.stdout
    1
    +4.0