2 % (c) The AQUA Project, Glasgow University, 1993-1995
4 \section[SimplUtils]{The simplifier utilities}
7 #include "HsVersions.h"
13 mkCoTyLamTryingEta, mkCoLamTryingEta,
19 simplIdWantsToBeINLINEd,
21 type_ok_for_let_to_case
24 IMPORT_Trace -- ToDo: rm (debugging)
34 import AbsPrel ( primOpIsCheap, realWorldStateTy,
36 IF_ATTACK_PRAGMAS(COMMA realWorldTy)
37 IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
38 IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
40 import AbsUniType ( extractTyVarsFromTy, getTyVarMaybe, isPrimType,
41 splitTypeWithDictsAsArgs, getUniDataTyCon_maybe,
42 applyTy, isFunType, TyVar, TyVarTemplate
43 IF_ATTACK_PRAGMAS(COMMA cmpTyVar COMMA cmpClass)
45 import Id ( getInstantiatedDataConSig, isDataCon, getIdUniType,
46 getIdArity, isBottomingId, idWantsToBeINLINEd,
50 import CmdLineOpts ( SimplifierSwitch(..) )
51 import Maybes ( maybeToBool, Maybe(..) )
52 import Outputable -- isExported ...
59 The function @floatExposesHNF@ tells whether let/case floating will
60 expose a head normal form. It is passed booleans indicating the
65 :: Bool -- Float let(rec)s out of rhs
66 -> Bool -- Float cheap primops out of rhs
67 -> Bool -- OK to duplicate code
71 floatExposesHNF float_lets float_primops ok_to_dup rhs
74 try (CoCase (CoPrim _ _ _) (CoPrimAlts alts deflt) )
75 | float_primops && (null alts || ok_to_dup)
76 = or (try_deflt deflt : map try_alt alts)
78 try (CoLet bind body) | float_lets = try body
82 -- because it *will* become one.
83 -- likewise for `augment g h'
85 try (CoApp (CoTyApp (CoVar bld) _) _) | bld == buildId = True
86 try (CoApp (CoApp (CoTyApp (CoVar bld) _) _) _) | bld == augmentId = True
88 try other = manifestlyWHNF other
89 {- but *not* necessarily "manifestlyBottom other"...
91 We may want to float a let out of a let to expose WHNFs,
92 but to do that to expose a "bottom" is a Bad Idea:
94 in ...error ...y... -- manifestly bottom using y
98 in let x = ...error ...y...
101 as y is only used in case of an error, we do not want
102 to allocate it eagerly as that's a waste.
105 try_alt (lit,rhs) = try rhs
107 try_deflt CoNoDefault = False
108 try_deflt (CoBindDefault _ rhs) = try rhs
112 Eta reduction on ordinary lambdas
113 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114 We have a go at doing
116 \ x y -> f x y ===> f
118 But we only do this if it gets rid of a whole lambda, not part.
119 The idea is that lambdas are often quite helpful: they indicate
120 head normal forms, so we don't want to chuck them away lightly.
121 But if they expose a simple variable then we definitely win. Even
122 if they expose a type application we win. So we check for this special
127 f xs = [y | (y,_) <- xs]
129 gives rise to a recursive function for the list comprehension, and
130 f turns out to be just a single call to this recursive function.
133 mkCoLamTryingEta :: [Id] -- Args to the lambda
134 -> PlainCoreExpr -- Lambda body
137 mkCoLamTryingEta [] body = body
139 mkCoLamTryingEta orig_ids body
140 = reduce_it (reverse orig_ids) body
142 bale_out = mkCoLam orig_ids body
144 reduce_it [] residual
145 | residual_ok residual = residual
146 | otherwise = bale_out
148 reduce_it (id:ids) (CoApp fun (CoVarAtom arg))
150 && getIdUniType id /= realWorldStateTy
151 -- *never* eta-reduce away a PrimIO state token! (WDP 94/11)
154 reduce_it ids other = bale_out
156 is_elem = isIn "mkCoLamTryingEta"
159 residual_ok :: PlainCoreExpr -> Bool -- Checks for type application
160 -- and function not one of the
162 residual_ok (CoTyApp fun ty) = residual_ok fun
163 residual_ok (CoVar v) = not (v `is_elem` orig_ids) -- Fun mustn't be one of
165 residual_ok other = False
170 @etaExpandCount@ takes an expression, E, and returns an integer n,
173 E ===> (\x1::t1 x1::t2 ... xn::tn -> E x1 x2 ... xn)
175 is a safe transformation. In particular, the transformation should not
176 cause work to be duplicated, unless it is ``cheap'' (see @manifestlyCheap@ below).
178 @etaExpandCount@ errs on the conservative side. It is always safe to return 0.
180 An application of @error@ is special, because it can absorb as many
181 arguments as you care to give it. For this special case we return 100,
182 to represent "infinity", which is a bit of a hack.
185 etaExpandCount :: CoreExpr bdr Id
186 -> Int -- Number of extra args you can safely abstract
188 etaExpandCount (CoLam ids body)
189 = length ids + etaExpandCount body
191 etaExpandCount (CoLet bind body)
192 | all manifestlyCheap (rhssOfBind bind)
193 = etaExpandCount body
195 etaExpandCount (CoCase scrut alts)
196 | manifestlyCheap scrut
197 = minimum [etaExpandCount rhs | rhs <- rhssOfAlts alts]
199 etaExpandCount (CoApp fun _) = case etaExpandCount fun of
201 n -> n-1 -- Knock off one
203 etaExpandCount fun@(CoTyApp _ _) = eta_fun fun
204 etaExpandCount fun@(CoVar _) = eta_fun fun
206 etaExpandCount other = 0 -- Give up
207 -- CoLit, CoCon, CoPrim,
209 -- CoScc (pessimistic; ToDo),
210 -- CoLet with non-whnf rhs(s),
211 -- CoCase with non-whnf scrutinee
213 eta_fun :: CoreExpr bdr Id -- The function
214 -> Int -- How many args it can safely be applied to
216 eta_fun (CoTyApp fun ty) = eta_fun fun
218 eta_fun expr@(CoVar v)
219 | isBottomingId v -- Bottoming ids have "infinite arity"
220 = 10000 -- Blargh. Infinite enough!
222 eta_fun expr@(CoVar v)
223 | maybeToBool arity_maybe -- We know the arity
226 arity_maybe = arityMaybe (getIdArity v)
227 arity = case arity_maybe of { Just arity -> arity }
229 eta_fun other = 0 -- Give up
232 @manifestlyCheap@ looks at a Core expression and returns \tr{True} if
233 it is obviously in weak head normal form, or is cheap to get to WHNF.
234 By ``cheap'' we mean a computation we're willing to duplicate in order
235 to bring a couple of lambdas together. The main examples of things
236 which aren't WHNF but are ``cheap'' are:
241 where e, and all the ei are cheap; and
246 where e and b are cheap; and
250 where op is a cheap primitive operator
253 manifestlyCheap :: CoreExpr bndr Id -> Bool
255 manifestlyCheap (CoVar _) = True
256 manifestlyCheap (CoLit _) = True
257 manifestlyCheap (CoCon _ _ _) = True
258 manifestlyCheap (CoLam _ _) = True
259 manifestlyCheap (CoTyLam _ e) = manifestlyCheap e
260 manifestlyCheap (CoSCC _ e) = manifestlyCheap e
262 manifestlyCheap (CoPrim op _ _) = primOpIsCheap op
264 manifestlyCheap (CoLet bind body)
265 = manifestlyCheap body && all manifestlyCheap (rhssOfBind bind)
267 manifestlyCheap (CoCase scrut alts)
268 = manifestlyCheap scrut && all manifestlyCheap (rhssOfAlts alts)
270 manifestlyCheap other_expr -- look for manifest partial application
271 = case (collectArgs other_expr) of { (fun, args) ->
274 CoVar f | isBottomingId f -> True -- Application of a function which
275 -- always gives bottom; we treat this as
276 -- a WHNF, because it certainly doesn't
277 -- need to be shared!
280 num_val_args = length [ a | (ValArg a) <- args ]
282 num_val_args == 0 || -- Just a type application of
283 -- a variable (f t1 t2 t3)
285 case (arityMaybe (getIdArity f)) of
287 Just arity -> num_val_args < arity
293 -- ToDo: Move to CoreFuns
295 rhssOfBind :: CoreBinding bndr bdee -> [CoreExpr bndr bdee]
297 rhssOfBind (CoNonRec _ rhs) = [rhs]
298 rhssOfBind (CoRec pairs) = [rhs | (_,rhs) <- pairs]
300 rhssOfAlts :: CoreCaseAlternatives bndr bdee -> [CoreExpr bndr bdee]
302 rhssOfAlts (CoAlgAlts alts deflt) = rhssOfDeflt deflt ++
303 [rhs | (_,_,rhs) <- alts]
304 rhssOfAlts (CoPrimAlts alts deflt) = rhssOfDeflt deflt ++
305 [rhs | (_,rhs) <- alts]
306 rhssOfDeflt CoNoDefault = []
307 rhssOfDeflt (CoBindDefault _ rhs) = [rhs]
310 Eta reduction on type lambdas
311 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
312 We have a go at doing
314 /\a -> <expr> a ===> <expr>
316 where <expr> doesn't mention a.
317 This is sometimes quite useful, because we can get the sequence:
319 f ab d = let d1 = ...d... in
320 letrec f' b x = ...d...(f' b)... in
324 f.Int b = letrec f' b x = ...dInt...(f' b)... in
329 f' b x = ...dInt...(f' b)...
332 Now we really want to simplify to
336 and then replace all the f's with f.Ints.
338 N.B. We are careful not to partially eta-reduce a sequence of type
339 applications since this breaks the specialiser:
341 /\ a -> f Char# a =NO=> f Char#
344 mkCoTyLamTryingEta :: [TyVar] -> PlainCoreExpr -> PlainCoreExpr
346 mkCoTyLamTryingEta tyvars tylam_body
348 tyvars == tyvar_args && -- Same args in same order
349 check_fun fun -- Function left is ok
351 -- Eta reduction worked
354 -- The vastly common case
355 mkCoTyLam tyvars tylam_body
357 (tyvar_args, fun) = strip_tyvar_args [] tylam_body
359 strip_tyvar_args args_so_far tyapp@(CoTyApp fun ty)
360 = case getTyVarMaybe ty of
361 Just tyvar_arg -> strip_tyvar_args (tyvar_arg:args_so_far) fun
362 Nothing -> (args_so_far, tyapp)
364 strip_tyvar_args args_so_far fun
367 check_fun (CoVar f) = True -- Claim: tyvars not mentioned by type of f
368 check_fun other = False
371 mkCoTyLamTryingEta :: TyVar -> PlainCoreExpr -> PlainCoreExpr
373 mkCoTyLamTryingEta tyvar body
376 case getTyVarMaybe ty of
377 Just tyvar' | tyvar == tyvar' &&
379 -- Ha! So it's /\ a -> fun a, and fun is "ok"
381 other -> CoTyLam tyvar body
382 other -> CoTyLam tyvar body
384 is_elem = isIn "mkCoTyLamTryingEta"
386 ok :: PlainCoreExpr -> Bool -- Returns True iff the expression doesn't
389 ok (CoVar v) = True -- Claim: tyvar not mentioned by type of v
390 ok (CoApp fun arg) = ok fun -- Claim: tyvar not mentioned by type of arg
391 ok (CoTyApp fun ty) = not (tyvar `is_elem` extractTyVarsFromTy ty) &&
400 Given a type generate the case alternatives
404 if there's one constructor, or
408 if there's many, or if it's a primitive type.
413 :: UniType -- type of RHS
414 -> SmplM InAlts -- result
416 mkIdentityAlts rhs_ty
418 = newId rhs_ty `thenSmpl` \ binder ->
419 returnSmpl (CoPrimAlts [] (CoBindDefault (binder, bad_occ_info) (CoVar binder)))
422 = case getUniDataTyCon_maybe rhs_ty of
423 Just (tycon, ty_args, [data_con]) -> -- algebraic type suitable for unpacking
425 (_,inst_con_arg_tys,_) = getInstantiatedDataConSig data_con ty_args
427 newIds inst_con_arg_tys `thenSmpl` \ new_bindees ->
429 new_binders = [ (b, bad_occ_info) | b <- new_bindees ]
433 [(data_con, new_binders, CoCon data_con ty_args (map CoVarAtom new_bindees))]
437 _ -> -- Multi-constructor or abstract algebraic type
438 newId rhs_ty `thenSmpl` \ binder ->
439 returnSmpl (CoAlgAlts [] (CoBindDefault (binder,bad_occ_info) (CoVar binder)))
441 bad_occ_info = ManyOcc 0 -- Non-committal!
445 simplIdWantsToBeINLINEd :: Id -> SimplEnv -> Bool
447 simplIdWantsToBeINLINEd id env
448 = if switchIsSet env IgnoreINLINEPragma
450 else idWantsToBeINLINEd id
452 type_ok_for_let_to_case :: UniType -> Bool
454 type_ok_for_let_to_case ty
455 = case getUniDataTyCon_maybe ty of
457 Just (tycon, ty_args, []) -> False
458 Just (tycon, ty_args, non_null_data_cons) -> True
459 -- Null data cons => type is abstract