2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[CoreUnfold]{Core-syntax unfoldings}
6 Unfoldings (which can travel across module boundaries) are in Core
7 syntax (namely @CoreExpr@s).
9 The type @Unfolding@ sits ``above'' simply-Core-expressions
10 unfoldings, capturing ``higher-level'' things we know about a binding,
11 usually things that the simplifier found out (e.g., ``it's a
12 literal''). In the corner of a @CoreUnfolding@ unfolding, you will
13 find, unsurprisingly, a Core expression.
17 Unfolding(..), UnfoldingGuidance(..), -- types
19 FormSummary(..), mkFormSummary, whnfOrBottom, exprSmallEnoughToDup,
22 noUnfolding, mkMagicUnfolding, mkUnfolding, getUnfoldingTemplate,
24 smallEnoughToInline, couldBeSmallEnoughToInline,
25 certainlySmallEnoughToInline, inlineUnconditionally, okToInline,
30 #include "HsVersions.h"
32 import {-# SOURCE #-} MagicUFs ( MagicUnfoldingFun, mkMagicUnfoldingFun )
34 import CmdLineOpts ( opt_UnfoldingCreationThreshold,
35 opt_UnfoldingUseThreshold,
36 opt_UnfoldingConDiscount,
37 opt_UnfoldingKeenessFactor
39 import Constants ( uNFOLDING_CHEAP_OP_COST,
40 uNFOLDING_DEAR_OP_COST,
41 uNFOLDING_NOREP_LIT_COST
43 import BinderInfo ( BinderInfo, isOneSameSCCFunOcc, isDeadOcc,
44 isInlinableOcc, isOneSafeFunOcc
47 import Literal ( Literal )
48 import CoreUtils ( unTagBinders )
49 import OccurAnal ( occurAnalyseGlobalExpr )
50 import CoreUtils ( coreExprType )
51 import Id ( Id, idType, getIdArity, isBottomingId, isDataCon,
52 idWantsToBeINLINEd, idMustBeINLINEd, idMustNotBeINLINEd,
54 import PrimOp ( fragilePrimOp, primOpCanTriggerGC )
55 import IdInfo ( ArityInfo(..), InlinePragInfo(..) )
56 import Literal ( isNoRepLit )
57 import TyCon ( tyConFamilySize )
58 import Type ( splitAlgTyConApp_maybe )
59 import Unique ( Unique )
60 import Util ( isIn, panic, assertPanic )
64 %************************************************************************
66 \subsection{@Unfolding@ and @UnfoldingGuidance@ types}
68 %************************************************************************
74 | OtherLit [Literal] -- It ain't one of these
75 | OtherCon [Id] -- It ain't one of these
77 | CoreUnfolding -- An unfolding with redundant cached information
78 FormSummary -- Tells whether the template is a WHNF or bottom
79 UnfoldingGuidance -- Tells about the *size* of the template.
80 SimplifiableCoreExpr -- Template
83 Unique -- Unique of the Id whose magic unfolding this is
88 noUnfolding = NoUnfolding
92 -- strictness mangling (depends on there being no CSE)
93 ufg = calcUnfoldingGuidance opt_UnfoldingCreationThreshold expr
94 occ = occurAnalyseGlobalExpr expr
95 cuf = CoreUnfolding (mkFormSummary expr) ufg occ
97 cont = case occ of { Var _ -> cuf; _ -> cuf }
99 case ufg of { UnfoldAlways -> cont; _ -> cont }
101 mkMagicUnfolding :: Unique -> Unfolding
102 mkMagicUnfolding tag = MagicUnfolding tag (mkMagicUnfoldingFun tag)
104 getUnfoldingTemplate :: Unfolding -> CoreExpr
105 getUnfoldingTemplate (CoreUnfolding _ _ expr)
107 getUnfoldingTemplate other = panic "getUnfoldingTemplate"
110 data UnfoldingGuidance
112 | UnfoldAlways -- There is no "original" definition,
113 -- so you'd better unfold. Or: something
114 -- so cheap to unfold (e.g., 1#) that
115 -- you should do it absolutely always.
117 | UnfoldIfGoodArgs Int -- if "m" type args
118 Int -- and "n" value args
120 [Int] -- Discount if the argument is evaluated.
121 -- (i.e., a simplification will definitely
122 -- be possible). One elt of the list per *value* arg.
124 Int -- The "size" of the unfolding; to be elaborated
127 Int -- Scrutinee discount: the discount to substract if the thing is in
128 -- a context (case (thing args) of ...),
129 -- (where there are the right number of arguments.)
133 instance Outputable UnfoldingGuidance where
134 ppr UnfoldAlways = ptext SLIT("_ALWAYS_")
135 ppr (UnfoldIfGoodArgs t v cs size discount)
136 = hsep [ptext SLIT("_IF_ARGS_"), int t, int v,
137 if null cs -- always print *something*
139 else hcat (map (text . show) cs),
145 %************************************************************************
147 \subsection{Figuring out things about expressions}
149 %************************************************************************
153 = VarForm -- Expression is a variable (or scc var, etc)
154 | ValueForm -- Expression is a value: i.e. a value-lambda,constructor, or literal
155 | BottomForm -- Expression is guaranteed to be bottom. We're more gung
156 -- ho about inlining such things, because it can't waste work
157 | OtherForm -- Anything else
159 instance Outputable FormSummary where
160 ppr VarForm = ptext SLIT("Var")
161 ppr ValueForm = ptext SLIT("Value")
162 ppr BottomForm = ptext SLIT("Bot")
163 ppr OtherForm = ptext SLIT("Other")
165 mkFormSummary ::GenCoreExpr bndr Id flexi -> FormSummary
168 = go (0::Int) expr -- The "n" is the number of (value) arguments so far
170 go n (Lit _) = ASSERT(n==0) ValueForm
171 go n (Con _ _) = ASSERT(n==0) ValueForm
172 go n (Prim _ _) = OtherForm
173 go n (Note _ e) = go n e
175 go n (Let (NonRec b r) e) | exprIsTrivial r = go n e -- let f = f' alpha in (f,g)
176 -- should be treated as a value
177 go n (Let _ e) = OtherForm
178 go n (Case _ _) = OtherForm
180 go 0 (Lam (ValBinder x) e) = ValueForm -- NB: \x.bottom /= bottom!
181 go n (Lam (ValBinder x) e) = go (n-1) e -- Applied lambda
182 go n (Lam other_binder e) = go n e
184 go n (App fun arg) | isValArg arg = go (n+1) fun
185 go n (App fun other_arg) = go n fun
187 go n (Var f) | isBottomingId f = BottomForm
188 | isDataCon f = ValueForm -- Can happen inside imported unfoldings
189 go 0 (Var f) = VarForm
190 go n (Var f) = case getIdArity f of
191 ArityExactly a | n < a -> ValueForm
192 ArityAtLeast a | n < a -> ValueForm
195 whnfOrBottom :: FormSummary -> Bool
196 whnfOrBottom VarForm = True
197 whnfOrBottom ValueForm = True
198 whnfOrBottom BottomForm = True
199 whnfOrBottom OtherForm = False
202 @exprIsTrivial@ is true of expressions we are unconditionally happy to duplicate;
203 simple variables and constants, and type applications.
206 exprIsTrivial (Var v) = True
207 exprIsTrivial (Lit lit) = not (isNoRepLit lit)
208 exprIsTrivial (App e (TyArg _)) = exprIsTrivial e
209 exprIsTrivial (Note _ e) = exprIsTrivial e
210 exprIsTrivial other = False
214 exprSmallEnoughToDup (Con _ _) = True -- Could check # of args
215 exprSmallEnoughToDup (Prim op _) = not (fragilePrimOp op) -- Could check # of args
216 exprSmallEnoughToDup (Lit lit) = not (isNoRepLit lit)
217 exprSmallEnoughToDup (Note _ e) = exprSmallEnoughToDup e
218 exprSmallEnoughToDup expr
219 = case (collectArgs expr) of { (fun, _, vargs) ->
221 Var v | length vargs <= 4 -> True
228 %************************************************************************
230 \subsection[calcUnfoldingGuidance]{Calculate ``unfolding guidance'' for an expression}
232 %************************************************************************
235 calcUnfoldingGuidance
236 :: Int -- bomb out if size gets bigger than this
237 -> CoreExpr -- expression to look at
240 calcUnfoldingGuidance bOMB_OUT_SIZE expr
241 = case collectBinders expr of { (ty_binders, val_binders, body) ->
242 case (sizeExpr bOMB_OUT_SIZE val_binders body) of
244 TooBig -> UnfoldNever
246 SizeIs size cased_args scrut_discount
250 (map discount_for val_binders)
255 | is_data && b `is_elem` cased_args = tyConFamilySize tycon
259 = case (splitAlgTyConApp_maybe (idType b)) of
260 Nothing -> (False, panic "discount")
261 Just (tc,_,_) -> (True, tc)
263 is_elem = isIn "calcUnfoldingGuidance" }
267 sizeExpr :: Int -- Bomb out if it gets bigger than this
268 -> [Id] -- Arguments; we're interested in which of these
273 sizeExpr (I# bOMB_OUT_SIZE) args expr
276 size_up (Var v) = sizeZero
277 size_up (Lit lit) | isNoRepLit lit = sizeN uNFOLDING_NOREP_LIT_COST
278 | otherwise = sizeZero
280 size_up (Note _ body) = size_up body -- Notes cost nothing
282 size_up (App fun arg) = size_up fun `addSize` size_up_arg arg
283 -- NB Zero cost for for type applications;
284 -- others cost 1 or more
286 size_up (Con con args) = conSizeN (numValArgs args)
287 -- We don't count 1 for the constructor because we're
288 -- quite keen to get constructors into the open
290 size_up (Prim op args) = sizeN op_cost -- NB: no charge for PrimOp args
292 op_cost = if primOpCanTriggerGC op
293 then uNFOLDING_DEAR_OP_COST
294 -- these *tend* to be more expensive;
295 -- number chosen to avoid unfolding (HACK)
296 else uNFOLDING_CHEAP_OP_COST
298 size_up expr@(Lam _ _)
300 (tyvars, args, body) = collectBinders expr
302 size_up body `addSizeN` length args
304 size_up (Let (NonRec binder rhs) body)
305 = nukeScrutDiscount (size_up rhs)
309 1 -- For the allocation
311 size_up (Let (Rec pairs) body)
312 = nukeScrutDiscount (foldr addSize sizeZero [size_up rhs | (_,rhs) <- pairs])
316 length pairs -- For the allocation
318 size_up (Case scrut alts)
319 = nukeScrutDiscount (size_up scrut)
323 size_up_alts (coreExprType scrut) alts
324 -- We charge for the "case" itself in "size_up_alts"
327 -- In an application we charge 0 for type application
328 -- 1 for most anything else
330 size_up_arg (LitArg lit) | isNoRepLit lit = sizeN uNFOLDING_NOREP_LIT_COST
331 size_up_arg (TyArg _) = sizeZero
332 size_up_arg other = sizeOne
335 size_up_alts scrut_ty (AlgAlts alts deflt)
336 = (foldr (addSize . size_alg_alt) (size_up_deflt deflt) alts)
340 size_alg_alt (con,args,rhs) = size_up rhs
341 -- Don't charge for args, so that wrappers look cheap
343 -- NB: we charge N for an alg. "case", where N is
344 -- the number of constructors in the thing being eval'd.
345 -- (You'll eventually get a "discount" of N if you
346 -- think the "case" is likely to go away.)
347 -- It's important to charge for alternatives. If you don't then you
348 -- get size 1 for things like:
349 -- case x of { A -> 1#; B -> 2#; ... lots }
353 = case (splitAlgTyConApp_maybe scrut_ty) of
355 Just (tc,_,_) -> tyConFamilySize tc
357 size_up_alts _ (PrimAlts alts deflt)
358 = foldr (addSize . size_prim_alt) (size_up_deflt deflt) alts
359 -- *no charge* for a primitive "case"!
361 size_prim_alt (lit,rhs) = size_up rhs
364 size_up_deflt NoDefault = sizeZero
365 size_up_deflt (BindDefault binder rhs) = size_up rhs
368 -- We want to record if we're case'ing an argument
369 arg_discount (Var v) | v `is_elem` args = scrutArg v
370 arg_discount other = sizeZero
372 is_elem :: Id -> [Id] -> Bool
373 is_elem = isIn "size_up_scrut"
376 -- These addSize things have to be here because
377 -- I don't want to give them bOMB_OUT_SIZE as an argument
379 addSizeN TooBig _ = TooBig
380 addSizeN (SizeIs n xs d) (I# m)
381 | n_tot -# d <# bOMB_OUT_SIZE = SizeIs n_tot xs d
386 addSize TooBig _ = TooBig
387 addSize _ TooBig = TooBig
388 addSize (SizeIs n1 xs d1) (SizeIs n2 ys d2)
389 | (n_tot -# d_tot) <# bOMB_OUT_SIZE = SizeIs n_tot xys d_tot
399 Code for manipulating sizes
403 data ExprSize = TooBig
404 | SizeIs Int# -- Size found
405 [Id] -- Arguments cased herein
406 Int# -- Size to subtract if result is scrutinised
407 -- by a case expression
409 sizeZero = SizeIs 0# [] 0#
410 sizeOne = SizeIs 1# [] 0#
411 sizeN (I# n) = SizeIs n [] 0#
412 conSizeN (I# n) = SizeIs n [] n
413 scrutArg v = SizeIs 0# [v] 0#
415 nukeScrutDiscount (SizeIs n vs d) = SizeIs n vs 0#
416 nukeScrutDiscount TooBig = TooBig
419 %************************************************************************
421 \subsection[considerUnfolding]{Given all the info, do (not) do the unfolding}
423 %************************************************************************
425 We have very limited information about an unfolding expression: (1)~so
426 many type arguments and so many value arguments expected---for our
427 purposes here, we assume we've got those. (2)~A ``size'' or ``cost,''
428 a single integer. (3)~An ``argument info'' vector. For this, what we
429 have at the moment is a Boolean per argument position that says, ``I
430 will look with great favour on an explicit constructor in this
431 position.'' (4)~The ``discount'' to subtract if the expression
432 is being scrutinised.
434 Assuming we have enough type- and value arguments (if not, we give up
435 immediately), then we see if the ``discounted size'' is below some
436 (semi-arbitrary) threshold. It works like this: for every argument
437 position where we're looking for a constructor AND WE HAVE ONE in our
438 hands, we get a (again, semi-arbitrary) discount [proportion to the
439 number of constructors in the type being scrutinized].
441 If we're in the context of a scrutinee ( \tr{(case <expr > of A .. -> ...;.. )})
442 and the expression in question will evaluate to a constructor, we use
443 the computed discount size *for the result only* rather than
444 computing the argument discounts. Since we know the result of
445 the expression is going to be taken apart, discounting its size
446 is more accurate (see @sizeExpr@ above for how this discount size
450 smallEnoughToInline :: Id -- The function (trace msg only)
451 -> [Bool] -- Evaluated-ness of value arguments
452 -> Bool -- Result is scrutinised
454 -> Bool -- True => unfold it
456 smallEnoughToInline _ _ _ UnfoldAlways = True
457 smallEnoughToInline _ _ _ UnfoldNever = False
458 smallEnoughToInline id arg_is_evald_s result_is_scruted
459 (UnfoldIfGoodArgs m_tys_wanted n_vals_wanted discount_vec size scrut_discount)
460 = if enough_args n_vals_wanted arg_is_evald_s &&
461 size - discount <= opt_UnfoldingUseThreshold
463 -- pprTrace "small enough" (ppr id <+> int size <+> int discount)
469 enough_args n [] | n > 0 = False -- A function with no value args => don't unfold
470 enough_args _ _ = True -- Otherwise it's ok to try
472 -- We multiple the raw discounts (args_discount and result_discount)
473 -- ty opt_UnfoldingKeenessFactor because the former have to do with
474 -- *size* whereas the discounts imply that there's some extra *efficiency*
475 -- to be gained (e.g. beta reductions, case reductions) by inlining.
478 opt_UnfoldingKeenessFactor *
479 fromInt (args_discount + result_discount)
482 args_discount = sum (zipWith arg_discount discount_vec arg_is_evald_s)
483 result_discount | result_is_scruted = scrut_discount
486 arg_discount no_of_constrs is_evald
487 | is_evald = no_of_constrs * opt_UnfoldingConDiscount
491 We use this one to avoid exporting inlinings that we ``couldn't possibly
492 use'' on the other side. Can be overridden w/ flaggery.
493 Just the same as smallEnoughToInline, except that it has no actual arguments.
496 couldBeSmallEnoughToInline :: Id -> UnfoldingGuidance -> Bool
497 couldBeSmallEnoughToInline id guidance = smallEnoughToInline id (repeat True) True guidance
499 certainlySmallEnoughToInline :: Id -> UnfoldingGuidance -> Bool
500 certainlySmallEnoughToInline id guidance = smallEnoughToInline id (repeat False) False guidance
506 @inlineUnconditionally@ decides whether a let-bound thing can
507 *definitely* be inlined at each of its call sites. If so, then
508 we can drop the binding right away. But remember, you have to be
509 certain that every use can be inlined. So, notably, any ArgOccs
510 rule this out. Since ManyOcc doesn't record FunOcc/ArgOcc
513 inlineUnconditionally :: (Id,BinderInfo) -> Bool
515 inlineUnconditionally (id, occ_info)
516 | idMustNotBeINLINEd id = False
518 | isOneSameSCCFunOcc occ_info
519 && idWantsToBeINLINEd id = True
521 | isOneSafeFunOcc occ_info
528 okToInline is used at call sites, so it is a bit more generous
531 okToInline :: Id -- The Id
532 -> Bool -- The thing is WHNF or bottom;
533 -> Bool -- It's small enough to duplicate the code
535 -> Bool -- True <=> inline it
537 okToInline id _ _ _ -- Check the Id first
538 | idWantsToBeINLINEd id = True
539 | idMustNotBeINLINEd id = False
541 okToInline id whnf small binder_info
543 | isDeadOcc binder_info
544 = pprTrace "okToInline: dead" (ppr id) False
547 = isInlinableOcc whnf small binder_info