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,
31 #include "HsVersions.h"
33 import {-# SOURCE #-} MagicUFs ( MagicUnfoldingFun, mkMagicUnfoldingFun )
35 import CmdLineOpts ( opt_UnfoldingCreationThreshold,
36 opt_UnfoldingUseThreshold,
37 opt_UnfoldingConDiscount,
38 opt_UnfoldingKeenessFactor,
41 import Constants ( uNFOLDING_CHEAP_OP_COST,
42 uNFOLDING_DEAR_OP_COST,
43 uNFOLDING_NOREP_LIT_COST
45 import BinderInfo ( BinderInfo, isOneSameSCCFunOcc, isDeadOcc,
46 isInlinableOcc, isOneSafeFunOcc
49 import Literal ( Literal )
50 import CoreUtils ( unTagBinders )
51 import OccurAnal ( occurAnalyseGlobalExpr )
52 import CoreUtils ( coreExprType )
53 import Id ( Id, idType, getIdArity, isBottomingId, isDataCon,
54 idWantsToBeINLINEd, idMustBeINLINEd, idMustNotBeINLINEd,
56 import PrimOp ( fragilePrimOp, primOpCanTriggerGC, PrimOp(..) )
57 import IdInfo ( ArityInfo(..), InlinePragInfo(..) )
58 import Name ( isExported )
59 import Literal ( isNoRepLit, isLitLitLit )
60 import TyCon ( tyConFamilySize )
61 import Type ( splitAlgTyConApp_maybe )
62 import Unique ( Unique )
63 import Util ( isIn, panic, assertPanic )
67 %************************************************************************
69 \subsection{@Unfolding@ and @UnfoldingGuidance@ types}
71 %************************************************************************
77 | OtherLit [Literal] -- It ain't one of these
78 | OtherCon [Id] -- It ain't one of these
80 | CoreUnfolding -- An unfolding with redundant cached information
81 FormSummary -- Tells whether the template is a WHNF or bottom
82 UnfoldingGuidance -- Tells about the *size* of the template.
83 SimplifiableCoreExpr -- Template
86 Unique -- Unique of the Id whose magic unfolding this is
91 noUnfolding = NoUnfolding
95 -- strictness mangling (depends on there being no CSE)
96 ufg = calcUnfoldingGuidance opt_UnfoldingCreationThreshold expr
97 occ = occurAnalyseGlobalExpr expr
98 cuf = CoreUnfolding (mkFormSummary expr) ufg occ
100 cont = case occ of { Var _ -> cuf; _ -> cuf }
102 case ufg of { UnfoldAlways -> cont; _ -> cont }
104 mkMagicUnfolding :: Unique -> Unfolding
105 mkMagicUnfolding tag = MagicUnfolding tag (mkMagicUnfoldingFun tag)
107 getUnfoldingTemplate :: Unfolding -> CoreExpr
108 getUnfoldingTemplate (CoreUnfolding _ _ expr)
110 getUnfoldingTemplate other = panic "getUnfoldingTemplate"
113 data UnfoldingGuidance
115 | UnfoldAlways -- There is no "original" definition,
116 -- so you'd better unfold. Or: something
117 -- so cheap to unfold (e.g., 1#) that
118 -- you should do it absolutely always.
120 | UnfoldIfGoodArgs Int -- if "m" type args
121 Int -- and "n" value args
123 [Int] -- Discount if the argument is evaluated.
124 -- (i.e., a simplification will definitely
125 -- be possible). One elt of the list per *value* arg.
127 Int -- The "size" of the unfolding; to be elaborated
130 Int -- Scrutinee discount: the discount to substract if the thing is in
131 -- a context (case (thing args) of ...),
132 -- (where there are the right number of arguments.)
136 instance Outputable UnfoldingGuidance where
137 ppr UnfoldAlways = ptext SLIT("_ALWAYS_")
138 ppr (UnfoldIfGoodArgs t v cs size discount)
139 = hsep [ptext SLIT("_IF_ARGS_"), int t, int v,
140 if null cs -- always print *something*
142 else hcat (map (text . show) cs),
148 %************************************************************************
150 \subsection{Figuring out things about expressions}
152 %************************************************************************
156 = VarForm -- Expression is a variable (or scc var, etc)
157 | ValueForm -- Expression is a value: i.e. a value-lambda,constructor, or literal
158 | BottomForm -- Expression is guaranteed to be bottom. We're more gung
159 -- ho about inlining such things, because it can't waste work
160 | OtherForm -- Anything else
162 instance Outputable FormSummary where
163 ppr VarForm = ptext SLIT("Var")
164 ppr ValueForm = ptext SLIT("Value")
165 ppr BottomForm = ptext SLIT("Bot")
166 ppr OtherForm = ptext SLIT("Other")
168 mkFormSummary ::GenCoreExpr bndr Id flexi -> FormSummary
171 = go (0::Int) expr -- The "n" is the number of (value) arguments so far
173 go n (Lit _) = ASSERT(n==0) ValueForm
174 go n (Con _ _) = ASSERT(n==0) ValueForm
175 go n (Prim _ _) = OtherForm
176 go n (Note _ e) = go n e
178 go n (Let (NonRec b r) e) | exprIsTrivial r = go n e -- let f = f' alpha in (f,g)
179 -- should be treated as a value
180 go n (Let _ e) = OtherForm
181 go n (Case _ _) = OtherForm
183 go 0 (Lam (ValBinder x) e) = ValueForm -- NB: \x.bottom /= bottom!
184 go n (Lam (ValBinder x) e) = go (n-1) e -- Applied lambda
185 go n (Lam other_binder e) = go n e
187 go n (App fun arg) | isValArg arg = go (n+1) fun
188 go n (App fun other_arg) = go n fun
190 go n (Var f) | isBottomingId f = BottomForm
191 | isDataCon f = ValueForm -- Can happen inside imported unfoldings
192 go 0 (Var f) = VarForm
193 go n (Var f) = case getIdArity f of
194 ArityExactly a | n < a -> ValueForm
195 ArityAtLeast a | n < a -> ValueForm
198 whnfOrBottom :: FormSummary -> Bool
199 whnfOrBottom VarForm = True
200 whnfOrBottom ValueForm = True
201 whnfOrBottom BottomForm = True
202 whnfOrBottom OtherForm = False
205 @exprIsTrivial@ is true of expressions we are unconditionally happy to duplicate;
206 simple variables and constants, and type applications.
209 exprIsTrivial (Var v) = True
210 exprIsTrivial (Lit lit) = not (isNoRepLit lit)
211 exprIsTrivial (App e (TyArg _)) = exprIsTrivial e
212 exprIsTrivial (Note _ e) = exprIsTrivial e
213 exprIsTrivial other = False
217 exprSmallEnoughToDup (Con _ _) = True -- Could check # of args
218 exprSmallEnoughToDup (Prim op _) = not (fragilePrimOp op) -- Could check # of args
219 exprSmallEnoughToDup (Lit lit) = not (isNoRepLit lit)
220 exprSmallEnoughToDup (Note _ e) = exprSmallEnoughToDup e
221 exprSmallEnoughToDup expr
222 = case (collectArgs expr) of { (fun, _, vargs) ->
224 Var v | length vargs <= 4 -> True
231 %************************************************************************
233 \subsection[calcUnfoldingGuidance]{Calculate ``unfolding guidance'' for an expression}
235 %************************************************************************
238 calcUnfoldingGuidance
239 :: Int -- bomb out if size gets bigger than this
240 -> CoreExpr -- expression to look at
242 calcUnfoldingGuidance bOMB_OUT_SIZE expr
243 = case collectBinders expr of { (ty_binders, val_binders, body) ->
244 case (sizeExpr bOMB_OUT_SIZE val_binders body) of
246 TooBig -> UnfoldNever
248 SizeIs size cased_args scrut_discount
252 (map discount_for val_binders)
257 | is_data && b `is_elem` cased_args = tyConFamilySize tycon
261 = case (splitAlgTyConApp_maybe (idType b)) of
262 Nothing -> (False, panic "discount")
263 Just (tc,_,_) -> (True, tc)
265 is_elem = isIn "calcUnfoldingGuidance" }
269 sizeExpr :: Int -- Bomb out if it gets bigger than this
270 -> [Id] -- Arguments; we're interested in which of these
275 sizeExpr (I# bOMB_OUT_SIZE) args expr
278 size_up (Var v) = sizeZero
279 size_up (Lit lit) | isNoRepLit lit = sizeN uNFOLDING_NOREP_LIT_COST
280 | otherwise = sizeZero
282 size_up (Note _ body) = size_up body -- Notes cost nothing
284 size_up (App fun arg) = size_up fun `addSize` size_up_arg arg
285 -- NB Zero cost for for type applications;
286 -- others cost 1 or more
288 size_up (Con con args) = conSizeN (numValArgs args)
289 -- We don't count 1 for the constructor because we're
290 -- quite keen to get constructors into the open
292 size_up (Prim op args) = sizeN op_cost -- NB: no charge for PrimOp args
294 op_cost = if primOpCanTriggerGC op
295 then uNFOLDING_DEAR_OP_COST
296 -- these *tend* to be more expensive;
297 -- number chosen to avoid unfolding (HACK)
298 else uNFOLDING_CHEAP_OP_COST
300 size_up expr@(Lam _ _)
302 (tyvars, args, body) = collectBinders expr
304 size_up body `addSizeN` length args
306 size_up (Let (NonRec binder rhs) body)
307 = nukeScrutDiscount (size_up rhs)
311 1 -- For the allocation
313 size_up (Let (Rec pairs) body)
314 = nukeScrutDiscount (foldr addSize sizeZero [size_up rhs | (_,rhs) <- pairs])
318 length pairs -- For the allocation
320 size_up (Case scrut alts)
321 = nukeScrutDiscount (size_up scrut)
325 size_up_alts (coreExprType scrut) alts
326 -- We charge for the "case" itself in "size_up_alts"
329 -- In an application we charge 0 for type application
330 -- 1 for most anything else
332 size_up_arg (LitArg lit) | isNoRepLit lit = sizeN uNFOLDING_NOREP_LIT_COST
333 size_up_arg (TyArg _) = sizeZero
334 size_up_arg other = sizeOne
337 size_up_alts scrut_ty (AlgAlts alts deflt)
338 = (foldr (addSize . size_alg_alt) (size_up_deflt deflt) alts)
342 size_alg_alt (con,args,rhs) = size_up rhs
343 -- Don't charge for args, so that wrappers look cheap
345 -- NB: we charge N for an alg. "case", where N is
346 -- the number of constructors in the thing being eval'd.
347 -- (You'll eventually get a "discount" of N if you
348 -- think the "case" is likely to go away.)
349 -- It's important to charge for alternatives. If you don't then you
350 -- get size 1 for things like:
351 -- case x of { A -> 1#; B -> 2#; ... lots }
355 = case (splitAlgTyConApp_maybe scrut_ty) of
357 Just (tc,_,_) -> tyConFamilySize tc
359 size_up_alts _ (PrimAlts alts deflt)
360 = foldr (addSize . size_prim_alt) (size_up_deflt deflt) alts
361 -- *no charge* for a primitive "case"!
363 size_prim_alt (lit,rhs) = size_up rhs
366 size_up_deflt NoDefault = sizeZero
367 size_up_deflt (BindDefault binder rhs) = size_up rhs
370 -- We want to record if we're case'ing an argument
371 arg_discount (Var v) | v `is_elem` args = scrutArg v
372 arg_discount other = sizeZero
374 is_elem :: Id -> [Id] -> Bool
375 is_elem = isIn "size_up_scrut"
378 -- These addSize things have to be here because
379 -- I don't want to give them bOMB_OUT_SIZE as an argument
381 addSizeN TooBig _ = TooBig
382 addSizeN (SizeIs n xs d) (I# m)
383 | n_tot -# d <# bOMB_OUT_SIZE = SizeIs n_tot xs d
388 addSize TooBig _ = TooBig
389 addSize _ TooBig = TooBig
390 addSize (SizeIs n1 xs d1) (SizeIs n2 ys d2)
391 | (n_tot -# d_tot) <# bOMB_OUT_SIZE = SizeIs n_tot xys d_tot
401 Code for manipulating sizes
405 data ExprSize = TooBig
406 | SizeIs Int# -- Size found
407 [Id] -- Arguments cased herein
408 Int# -- Size to subtract if result is scrutinised
409 -- by a case expression
411 sizeZero = SizeIs 0# [] 0#
412 sizeOne = SizeIs 1# [] 0#
413 sizeN (I# n) = SizeIs n [] 0#
414 conSizeN (I# n) = SizeIs n [] n
415 scrutArg v = SizeIs 0# [v] 0#
417 nukeScrutDiscount (SizeIs n vs d) = SizeIs n vs 0#
418 nukeScrutDiscount TooBig = TooBig
421 %************************************************************************
423 \subsection[considerUnfolding]{Given all the info, do (not) do the unfolding}
425 %************************************************************************
427 We have very limited information about an unfolding expression: (1)~so
428 many type arguments and so many value arguments expected---for our
429 purposes here, we assume we've got those. (2)~A ``size'' or ``cost,''
430 a single integer. (3)~An ``argument info'' vector. For this, what we
431 have at the moment is a Boolean per argument position that says, ``I
432 will look with great favour on an explicit constructor in this
433 position.'' (4)~The ``discount'' to subtract if the expression
434 is being scrutinised.
436 Assuming we have enough type- and value arguments (if not, we give up
437 immediately), then we see if the ``discounted size'' is below some
438 (semi-arbitrary) threshold. It works like this: for every argument
439 position where we're looking for a constructor AND WE HAVE ONE in our
440 hands, we get a (again, semi-arbitrary) discount [proportion to the
441 number of constructors in the type being scrutinized].
443 If we're in the context of a scrutinee ( \tr{(case <expr > of A .. -> ...;.. )})
444 and the expression in question will evaluate to a constructor, we use
445 the computed discount size *for the result only* rather than
446 computing the argument discounts. Since we know the result of
447 the expression is going to be taken apart, discounting its size
448 is more accurate (see @sizeExpr@ above for how this discount size
452 smallEnoughToInline :: Id -- The function (trace msg only)
453 -> [Bool] -- Evaluated-ness of value arguments
454 -> Bool -- Result is scrutinised
456 -> Bool -- True => unfold it
458 smallEnoughToInline _ _ _ UnfoldAlways = True
459 smallEnoughToInline _ _ _ UnfoldNever = False
460 smallEnoughToInline id arg_is_evald_s result_is_scruted
461 (UnfoldIfGoodArgs m_tys_wanted n_vals_wanted discount_vec size scrut_discount)
462 = if enough_args n_vals_wanted arg_is_evald_s &&
463 size - discount <= opt_UnfoldingUseThreshold
465 -- pprTrace "small enough" (ppr id <+> int size <+> int discount)
471 enough_args n [] | n > 0 = False -- A function with no value args => don't unfold
472 enough_args _ _ = True -- Otherwise it's ok to try
474 -- We multiple the raw discounts (args_discount and result_discount)
475 -- ty opt_UnfoldingKeenessFactor because the former have to do with
476 -- *size* whereas the discounts imply that there's some extra *efficiency*
477 -- to be gained (e.g. beta reductions, case reductions) by inlining.
480 opt_UnfoldingKeenessFactor *
481 fromInt (args_discount + result_discount)
484 args_discount = sum (zipWith arg_discount discount_vec arg_is_evald_s)
485 result_discount | result_is_scruted = scrut_discount
488 arg_discount no_of_constrs is_evald
489 | is_evald = no_of_constrs * opt_UnfoldingConDiscount
493 We use this one to avoid exporting inlinings that we ``couldn't possibly
494 use'' on the other side. Can be overridden w/ flaggery.
495 Just the same as smallEnoughToInline, except that it has no actual arguments.
498 couldBeSmallEnoughToInline :: Id -> UnfoldingGuidance -> Bool
499 couldBeSmallEnoughToInline id guidance = smallEnoughToInline id (repeat True) True guidance
501 certainlySmallEnoughToInline :: Id -> UnfoldingGuidance -> Bool
502 certainlySmallEnoughToInline id guidance = smallEnoughToInline id (repeat False) False guidance
508 @inlineUnconditionally@ decides whether a let-bound thing can
509 *definitely* be inlined at each of its call sites. If so, then
510 we can drop the binding right away. But remember, you have to be
511 certain that every use can be inlined. So, notably, any ArgOccs
512 rule this out. Since ManyOcc doesn't record FunOcc/ArgOcc
515 inlineUnconditionally :: (Id,BinderInfo) -> Bool
517 inlineUnconditionally (id, occ_info)
518 | idMustNotBeINLINEd id
522 | isOneSameSCCFunOcc occ_info
523 && idWantsToBeINLINEd id = True
525 | isOneSafeFunOcc occ_info
532 okToInline is used at call sites, so it is a bit more generous
535 okToInline :: Id -- The Id
536 -> Bool -- The thing is WHNF or bottom;
537 -> Bool -- It's small enough to duplicate the code
539 -> Bool -- True <=> inline it
541 okToInline id _ _ _ -- Check the Id first
542 | idWantsToBeINLINEd id = True
543 | idMustNotBeINLINEd id = False
545 okToInline id whnf small binder_info
547 | isDeadOcc binder_info
548 = pprTrace "okToInline: dead" (ppr id) False
551 = isInlinableOcc whnf small binder_info
554 @okToUnfoldInHifile@ is used when emitting unfolding info into an interface
555 file to determine whether an unfolding candidate really should be unfolded.
556 The predicate is needed to prevent @_casm_@s (+ lit-lits) from being emitted
557 into interface files.
559 The reason for inlining expressions containing _casm_s into interface files
560 is that these fragments of C are likely to mention functions/#defines that
561 will be out-of-scope when inlined into another module. This is not an
562 unfixable problem for the user (just need to -#include the approp. header
563 file), but turning it off seems to the simplest thing to do.
566 okToUnfoldInHiFile :: CoreExpr -> Bool
567 okToUnfoldInHiFile e = opt_UnfoldCasms || go e
569 -- Race over an expression looking for CCalls..
571 go (Lit lit) = not (isLitLitLit lit)
572 go (Note _ body) = go body
573 go (App fun arg) = go fun
574 go (Con con args) = True
575 go (Prim op args) = okToUnfoldPrimOp op
576 go (Lam _ body) = go body
577 go (Let (NonRec binder rhs) body) = go rhs && go body
578 go (Let (Rec pairs) body) = and (map go (body:rhses))
580 rhses = [ rhs | (_, rhs) <- pairs ]
581 go (Case scrut alts) = and (map go (scrut:rhses))
583 rhses = getAltRhs alts
585 getAltRhs (PrimAlts alts deflt) =
586 let ls = map snd alts in
589 BindDefault _ rhs -> rhs:ls
590 getAltRhs (AlgAlts alts deflt) =
591 let ls = map (\ (_,_,r) -> r) alts in
594 BindDefault _ rhs -> rhs:ls
596 -- ok to unfold a PrimOp as long as it's not a _casm_
597 okToUnfoldPrimOp (CCallOp _ is_casm _ _ _ _) = not is_casm
598 okToUnfoldPrimOp _ = True