never executed always true always false
1 module GHC.Core.UsageEnv
2 ( Usage(..)
3 , UsageEnv
4 , addUE
5 , addUsage
6 , bottomUE
7 , deleteUE
8 , lookupUE
9 , scaleUE
10 , scaleUsage
11 , supUE
12 , supUEs
13 , unitUE
14 , zeroUE
15 ) where
16
17 import Data.Foldable
18 import GHC.Prelude
19 import GHC.Core.Multiplicity
20 import GHC.Types.Name
21 import GHC.Types.Name.Env
22 import GHC.Utils.Outputable
23 import GHC.Utils.Panic
24
25 --
26 -- * Usage environments
27 --
28
29 -- The typechecker and the linter output usage environments. See Note [Usages]
30 -- in Multiplicity. Every absent name being considered to map to 'Zero' of
31 -- 'Bottom' depending on a flag. See Note [Zero as a usage] in Multiplicity, see
32 -- Note [Bottom as a usage] in Multiplicity.
33
34 data Usage = Zero | Bottom | MUsage Mult
35
36 instance Outputable Usage where
37 ppr Zero = text "0"
38 ppr Bottom = text "Bottom"
39 ppr (MUsage x) = ppr x
40
41 addUsage :: Usage -> Usage -> Usage
42 addUsage Zero x = x
43 addUsage x Zero = x
44 addUsage Bottom x = x
45 addUsage x Bottom = x
46 addUsage (MUsage x) (MUsage y) = MUsage $ mkMultAdd x y
47
48 scaleUsage :: Mult -> Usage -> Usage
49 scaleUsage One Bottom = Bottom
50 scaleUsage _ Zero = Zero
51 scaleUsage x Bottom = MUsage x
52 scaleUsage x (MUsage y) = MUsage $ mkMultMul x y
53
54 -- For now, we use extra multiplicity Bottom for empty case.
55 data UsageEnv = UsageEnv !(NameEnv Mult) Bool
56
57 unitUE :: NamedThing n => n -> Mult -> UsageEnv
58 unitUE x w = UsageEnv (unitNameEnv (getName x) w) False
59
60 zeroUE, bottomUE :: UsageEnv
61 zeroUE = UsageEnv emptyNameEnv False
62
63 bottomUE = UsageEnv emptyNameEnv True
64
65 addUE :: UsageEnv -> UsageEnv -> UsageEnv
66 addUE (UsageEnv e1 b1) (UsageEnv e2 b2) =
67 UsageEnv (plusNameEnv_C mkMultAdd e1 e2) (b1 || b2)
68
69 scaleUE :: Mult -> UsageEnv -> UsageEnv
70 scaleUE One ue = ue
71 scaleUE w (UsageEnv e _) =
72 UsageEnv (mapNameEnv (mkMultMul w) e) False
73
74 supUE :: UsageEnv -> UsageEnv -> UsageEnv
75 supUE (UsageEnv e1 False) (UsageEnv e2 False) =
76 UsageEnv (plusNameEnv_CD mkMultSup e1 Many e2 Many) False
77 supUE (UsageEnv e1 b1) (UsageEnv e2 b2) = UsageEnv (plusNameEnv_CD2 combineUsage e1 e2) (b1 && b2)
78 where combineUsage (Just x) (Just y) = mkMultSup x y
79 combineUsage Nothing (Just x) | b1 = x
80 | otherwise = Many
81 combineUsage (Just x) Nothing | b2 = x
82 | otherwise = Many
83 combineUsage Nothing Nothing = pprPanic "supUE" (ppr e1 <+> ppr e2)
84 -- Note: If you are changing this logic, check 'mkMultSup' in Multiplicity as well.
85
86 supUEs :: [UsageEnv] -> UsageEnv
87 supUEs = foldr supUE bottomUE
88
89
90 deleteUE :: NamedThing n => UsageEnv -> n -> UsageEnv
91 deleteUE (UsageEnv e b) x = UsageEnv (delFromNameEnv e (getName x)) b
92
93 -- | |lookupUE x env| returns the multiplicity assigned to |x| in |env|, if |x| is not
94 -- bound in |env|, then returns |Zero| or |Bottom|.
95 lookupUE :: NamedThing n => UsageEnv -> n -> Usage
96 lookupUE (UsageEnv e has_bottom) x =
97 case lookupNameEnv e (getName x) of
98 Just w -> MUsage w
99 Nothing -> if has_bottom then Bottom else Zero
100
101 instance Outputable UsageEnv where
102 ppr (UsageEnv ne b) = text "UsageEnv:" <+> ppr ne <+> ppr b