52f66506ac2efeb1fe47bc1074c1ce7d59cbc5b4
[ghc-hetmet.git] / ghc / compiler / stranal / SaLib.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
3 %
4 \section[SaLib]{Basic datatypes, functions for the strictness analyser}
5
6 See also: the ``library'' for the ``back end'' (@SaBackLib@).
7
8 \begin{code}
9 #include "HsVersions.h"
10
11 module SaLib (
12         AbsVal(..),
13         AnalysisKind(..),
14         AbsValEnv{-abstract-}, StrictEnv(..), AbsenceEnv(..),
15         StrAnalFlags(..), getStrAnalFlags,
16         nullAbsValEnv, addOneToAbsValEnv, growAbsValEnvList,
17         lookupAbsValEnv,
18         absValFromStrictness,
19
20         -- and to make the interface self-sufficient...
21         CoreExpr, Id, IdEnv(..), UniqFM, Unique,
22         Demand, PlainCoreExpr(..)
23     ) where
24
25 import IdEnv
26 import IdInfo
27 --import FiniteMap      -- debugging only
28 import Outputable
29 import PlainCore
30 import Pretty
31 import Util             -- for pragmas only
32 \end{code}
33
34 %************************************************************************
35 %*                                                                      *
36 \subsection[AbsVal-datatype]{@AbsVal@: abstract values (and @AbsValEnv@)}
37 %*                                                                      *
38 %************************************************************************
39
40 @AnalysisKind@ tells what kind of analysis is being done.
41
42 \begin{code}
43 data AnalysisKind
44   = StrAnal     -- We're doing strictness analysis
45   | AbsAnal     -- We're doing absence analysis
46   deriving Text
47 \end{code}
48
49 @AbsVal@ is the data type of HNF abstract values.
50
51 \begin{code}
52 data AbsVal
53   = AbsTop                  -- AbsTop is the completely uninformative
54                             -- value
55
56   | AbsBot                  -- An expression whose abstract value is
57                             -- AbsBot is sure to fail to terminate.
58                             -- AbsBot represents the abstract
59                             -- *function* bottom too.
60
61   | AbsProd [AbsVal]        -- (Lifted) product of abstract values
62                             -- "Lifted" means that AbsBot is *different* from
63                             --    AbsProd [AbsBot, ..., AbsBot]
64
65   | AbsFun                  -- An abstract function, with the given:
66             [Id]            -- arguments
67             PlainCoreExpr   -- body
68             AbsValEnv       -- and environment
69
70   | AbsApproxFun            -- This is used to represent a coarse
71             [Demand]        -- approximation to a function value.  It's an
72                             -- abstract function which is strict in its i'th
73                             -- argument if the i'th element of the Demand
74                             -- list so indicates.
75                             -- The list of arguments is always non-empty.
76                             -- In effect, AbsApproxFun [] = AbsTop 
77
78 instance Outputable AbsVal where
79     ppr sty AbsTop = ppStr "AbsTop"
80     ppr sty AbsBot = ppStr "AbsBot"
81     ppr sty (AbsProd prod) = ppCat [ppStr "AbsProd", ppr sty prod]
82     ppr sty (AbsFun args body env)
83       = ppCat [ppStr "AbsFun{", ppr sty args,
84                ppStr "???", -- ppStr "}{env:", ppr sty (keysFM env `zip` eltsFM env),
85                ppStr "}" ]
86     ppr sty (AbsApproxFun demands)
87       = ppCat [ppStr "AbsApprox{", ppr sty demands, ppStr "}" ]
88 \end{code}
89
90 %-----------
91
92 An @AbsValEnv@ maps @Ids@ to @AbsVals@.  Any unbound @Ids@ are
93 implicitly bound to @AbsTop@, the completely uninformative,
94 pessimistic value---see @absEval@ of a @CoVar@.
95
96 \begin{code}
97 data AbsValEnv = AbsValEnv StrAnalFlags (IdEnv AbsVal)
98
99 type StrAnalFlags
100   = (Bool,      -- True <=> AllStrict flag is set
101      Bool)      -- True <=> NumbersStrict flag is set
102
103 type StrictEnv  = AbsValEnv     -- Environment for strictness analysis
104 type AbsenceEnv = AbsValEnv     -- Environment for absence analysis
105
106 nullAbsValEnv flags -- this is the one and only way to create AbsValEnvs
107   = AbsValEnv flags nullIdEnv
108
109 addOneToAbsValEnv (AbsValEnv x idenv) y z = AbsValEnv x (addOneToIdEnv idenv y z)
110 growAbsValEnvList (AbsValEnv x idenv) ys  = AbsValEnv x (growIdEnvList idenv ys)
111
112 lookupAbsValEnv (AbsValEnv _ idenv) y
113   = lookupIdEnv idenv y
114
115 getStrAnalFlags (AbsValEnv flags _) = flags
116 \end{code}
117
118 \begin{code}
119 absValFromStrictness :: AnalysisKind -> StrictnessInfo -> AbsVal
120
121 absValFromStrictness anal NoStrictnessInfo             = AbsTop
122
123 absValFromStrictness StrAnal BottomGuaranteed          = AbsBot -- Guaranteed bottom
124 absValFromStrictness AbsAnal BottomGuaranteed          = AbsTop -- Check for poison in
125                                                                 -- arguments (if any)
126 absValFromStrictness anal (StrictnessInfo []        _) = AbsTop
127 absValFromStrictness anal (StrictnessInfo args_info _) = AbsApproxFun args_info
128 \end{code}