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