[project @ 1996-06-05 06:44:31 by partain]
[ghc-hetmet.git] / ghc / compiler / simplCore / AnalFBWW.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[AnalFBWW]{Spoting good functions for splitting into workers/wrappers}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module AnalFBWW ( analFBWW ) where
10
11 IMP_Ubiq(){-uitous-}
12
13 import CoreSyn          ( CoreBinding(..) )
14 import Util             ( panic{-ToDo:rm-} )
15
16 --import Util
17 --import Id                     ( addIdFBTypeInfo )
18 --import IdInfo
19 --import PrelInfo          ( foldrId, buildId,
20 --                        nilDataCon, consDataCon, mkListTy, mkFunTy,
21 --                        unpackCStringAppendId
22 --                      )
23 --import BinderInfo
24 --import SimplEnv               -- everything
25 --import OccurAnal      -- OLD: was NewOccurAnal
26 --import Maybes
27 \end{code}
28
29 \begin{code}
30 analFBWW
31         :: [CoreBinding]
32         -> [CoreBinding]
33
34 analFBWW = panic "analFBWW (ToDo)"
35
36 {- LATER:
37 analFBWW top_binds = trace "ANALFBWW" (snd anno)
38  where
39         anals :: [InBinding]
40         anals = newOccurAnalyseBinds top_binds (const False)
41         anno = mapAccumL annotateBindingFBWW nullIdEnv anals
42 \end{code}
43
44 \begin{code}
45 data OurFBType
46         = IsFB FBType
47         | IsNotFB               -- unknown
48         | IsCons                -- \ xy -> (:) ty xy
49         | IsBottom              -- _|_
50                 deriving (Eq)
51         -- We only handle *reasonable* types
52         -- Later might add concept of bottom
53         -- because foldr f z (<bottom>) = <bottom>
54 unknownFBType  = IsNotFB
55 goodProdFBType = IsFB (FBType [] FBGoodProd)
56
57 maybeFBtoFB (Just ty) = ty
58 maybeFBtoFB (Nothing) = IsNotFB
59
60 addArgs :: Int -> OurFBType -> OurFBType
61 addArgs n (IsFB (FBType args prod))
62         = IsFB (FBType (nOfThem n FBBadConsum ++ args) prod)
63 addArgs n IsNotFB = IsNotFB
64 addArgs n IsCons = panic "adding argument to a cons"
65 addArgs n IsBottom = IsNotFB
66
67 rmArg :: OurFBType -> OurFBType
68 rmArg (IsFB (FBType [] prod)) = IsNotFB -- panic "removing argument from producer"
69 rmArg (IsFB (FBType args prod)) = IsFB (FBType (tail args) prod)
70 rmArg IsBottom = IsBottom
71 rmArg _ = IsNotFB
72
73 joinFBType :: OurFBType -> OurFBType -> OurFBType
74 joinFBType (IsBottom) a = a
75 joinFBType a (IsBottom) = a
76 joinFBType (IsFB (FBType args prod)) (IsFB (FBType args' prod'))
77         | length args == length args' = (IsFB (FBType (zipWith{-Equal-} argJ args args')
78                                                       (prodJ prod prod')))
79    where
80         argJ FBGoodConsum FBGoodConsum = FBGoodConsum
81         argJ _            _            = FBBadConsum
82         prodJ FBGoodProd FBGoodProd    = FBGoodProd
83         prodJ _                   _    = FBBadProd
84
85 joinFBType _ _ = IsNotFB
86
87 --
88 -- Mutter :: IdEnv FBType need to be in an *inlinable* context.
89 --
90
91 analExprFBWW :: InExpr -> IdEnv OurFBType -> OurFBType
92
93 --
94 -- [ build g ]          is a good context
95 --
96 analExprFBWW (App (CoTyApp (Var bld) _) _) env
97         | bld == buildId         = goodProdFBType
98
99 --
100 -- [ foldr (:) ys xs ] ==> good
101 --                      (but better if xs)
102 --
103 analExprFBWW (App (App (App
104                 (CoTyApp (CoTyApp (Var foldr_id) _) _) (VarArg c)) _) _)
105                 env
106         | pprTrace ("FOLDR:" ++ show (foldr_id == foldrId,isCons c))
107                 (ppr PprDebug foldr_id)
108                 (foldr_id == foldrId && isCons c) = goodProdFBType
109    where
110         isCons c = case lookupIdEnv env c of
111                     Just IsCons -> True
112                     _ -> False
113 analExprFBWW (Var v) env       = maybeFBtoFB (lookupIdEnv env v)
114 analExprFBWW (Lit _) _         = unknownFBType
115
116 --
117 -- [ x : xs ]  ==> good iff [ xs ] is good
118 --
119
120 analExprFBWW (Con con _ [_,VarArg y]) env
121         | con == consDataCon = maybeFBtoFB (lookupIdEnv env y)
122 --
123 -- [] is good
124 --
125 analExprFBWW (Con con _ []) _
126         | con == nilDataCon = goodProdFBType
127 analExprFBWW (Con _ _ _) _     = unknownFBType
128 analExprFBWW (Prim _ _ _) _    = unknownFBType
129
130 -- \ xy -> (:) ty xy == a CONS
131
132 analExprFBWW (Lam (x,_) (Lam (y,_)
133                 (Con con _ [VarArg x',VarArg y']))) env
134   | con == consDataCon && x == x' && y == y'
135   = IsCons
136 analExprFBWW (Lam (id,_) e) env
137   = addArgs 1 (analExprFBWW e (delOneFromIdEnv env id))
138
139 analExprFBWW (CoTyLam tyvar e) env = analExprFBWW e env
140 analExprFBWW (App f atom) env  = rmArg (analExprFBWW f env)
141 analExprFBWW (CoTyApp f ty) env  = analExprFBWW f env
142 analExprFBWW (SCC lab e) env   = analExprFBWW e env
143 analExprFBWW (Coerce _ _ _) env   = panic "AnalFBWW:analExprFBWW:Coerce"
144 analExprFBWW (Let binds e) env = analExprFBWW e (analBind binds env)
145 analExprFBWW (Case e alts) env = foldl1 joinFBType (analAltsFBWW alts env)
146
147 analAltsFBWW (AlgAlts alts deflt) env
148   = case analDefFBWW deflt env of
149         Just ty -> ty : tys
150         Nothing -> tys
151    where
152      tys = map (\(con,binders,e) -> analExprFBWW e (delManyFromIdEnv env (map fst binders))) alts
153 analAltsFBWW (PrimAlts alts deflt) env
154   = case analDefFBWW deflt env of
155         Just ty -> ty : tys
156         Nothing -> tys
157    where
158      tys = map (\(lit,e) -> analExprFBWW e env) alts
159
160
161 analDefFBWW NoDefault env = Nothing
162 analDefFBWW (BindDefault v e) env = Just (analExprFBWW e (delOneFromIdEnv env (fst v)))
163 \end{code}
164
165
166 Only add a type info if:
167
168 1. Is a functionn.
169 2. Is an inlineable object.
170
171 \begin{code}
172 analBindExpr :: BinderInfo -> InExpr -> IdEnv OurFBType -> OurFBType
173 analBindExpr bnd expr env
174   =    case analExprFBWW expr env of
175               IsFB ty@(FBType [] _) ->
176                    if oneSafeOcc False bnd
177                    then IsFB ty
178                    else IsNotFB
179               other -> other
180
181 analBind :: InBinding -> IdEnv OurFBType -> IdEnv OurFBType
182 analBind (NonRec (v,bnd) e) env =
183         case analBindExpr bnd e env of
184          ty@(IsFB _) -> addOneToIdEnv env v ty
185          ty@(IsCons) -> addOneToIdEnv env v ty
186          _ -> delOneFromIdEnv env v     -- remember about shadowing!
187
188 analBind (Rec binds) env =
189    let
190         first_set = [ (v,IsFB (FBType [FBBadConsum | _ <- args ] FBGoodProd)) | ((v,_),e) <- binds,
191                                 (_,_,args,_) <- [collectBinders e]]
192         env' = delManyFromIdEnv env (map (fst.fst) binds)
193    in
194         growIdEnvList env' (fixpoint 0 binds env' first_set)
195
196 fixpoint :: Int -> [(InBinder,InExpr)] -> IdEnv OurFBType -> [(Id,OurFBType)] -> [(Id,OurFBType)]
197 fixpoint n binds env maps =
198         if maps == maps'
199         then maps
200         else fixpoint (n+1) binds env maps'
201    where
202         env' = growIdEnvList env maps
203         maps' = [ (v,ty) | ((v,bind),e) <- binds,
204                         (ty@(IsFB (FBType cons prod))) <- [analBindExpr bind e env']]
205
206 \end{code}
207
208
209 \begin{code}
210 annotateExprFBWW :: InExpr -> IdEnv OurFBType -> CoreExpr
211 annotateExprFBWW (Var v) env = Var v
212 annotateExprFBWW (Lit i) env = Lit i
213 annotateExprFBWW (Con c t a) env = Con c t a
214 annotateExprFBWW (Prim p t a) env = Prim p t a
215 annotateExprFBWW (Lam (id,_) e) env
216   = Lam id (annotateExprFBWW e (delOneFromIdEnv env id))
217
218 annotateExprFBWW (CoTyLam tyvar e) env = CoTyLam tyvar (annotateExprFBWW e env)
219 annotateExprFBWW (App f atom) env = App (annotateExprFBWW f env) atom
220 annotateExprFBWW (CoTyApp f ty) env = CoTyApp (annotateExprFBWW f env) ty
221 annotateExprFBWW (SCC lab e) env = SCC lab (annotateExprFBWW e env)
222 annotateExprFBWW (Coerce c ty e) env = Coerce c ty (annotateExprFBWW e env)
223 annotateExprFBWW (Case e alts) env = Case (annotateExprFBWW e env)
224                                             (annotateAltsFBWW alts env)
225 annotateExprFBWW (Let bnds e) env = Let bnds' (annotateExprFBWW e env')
226   where
227         (env',bnds') = annotateBindingFBWW env bnds
228
229 annotateAltsFBWW (AlgAlts alts deflt) env = AlgAlts alts' deflt'
230   where
231         alts' = [ let
232                    binders' = map fst binders
233                   in (con,binders',annotateExprFBWW e (delManyFromIdEnv env binders'))
234                                 | (con,binders,e) <- alts ]
235         deflt' = annotateDefFBWW deflt env
236 annotateAltsFBWW (PrimAlts alts deflt) env = PrimAlts alts' deflt'
237   where
238         alts' = [ (lit,annotateExprFBWW e env) | (lit,e) <- alts ]
239         deflt' = annotateDefFBWW deflt env
240
241 annotateDefFBWW NoDefault env = NoDefault
242 annotateDefFBWW (BindDefault v e) env
243         = BindDefault (fst v) (annotateExprFBWW e (delOneFromIdEnv env (fst v)))
244
245 annotateBindingFBWW :: IdEnv OurFBType -> InBinding -> (IdEnv OurFBType,CoreBinding)
246 annotateBindingFBWW env bnds = (env',bnds')
247   where
248         env' = analBind bnds env
249         bnds' = case bnds of
250                   NonRec (v,_) e -> NonRec (fixId v) (annotateExprFBWW e env)
251                   Rec bnds -> Rec [ (fixId v,annotateExprFBWW e env') | ((v,_),e) <- bnds ]
252         fixId v =
253                 (case lookupIdEnv env' v of
254                    Just (IsFB ty@(FBType xs p))
255                     | not (null xs) -> pprTrace "ADDED to:" (ppr PprDebug v)
256                                         (addIdFBTypeInfo v (mkFBTypeInfo ty))
257                    _ -> v)
258 -}
259 \end{code}