- size_up (Case scrut _ alts)
- = nukeScrutDiscount (size_up scrut) `addSize`
- arg_discount scrut `addSize`
- foldr (addSize . size_up_alt) sizeZero alts
- `addSizeN` 1 -- charge one for the case itself.
-
--- Just charge for the alts that exist, not the ones that might exist
--- `addSizeN`
--- case (splitAlgTyConApp_maybe (coreExprType scrut)) of
--- Nothing -> 1
--- Just (tc,_,_) -> tyConFamilySize tc
+ -- We want to make wrapper-style evaluation look cheap, so that
+ -- when we inline a wrapper it doesn't make call site (much) bigger
+ -- Otherwise we get nasty phase ordering stuff:
+ -- f x = g x x
+ -- h y = ...(f e)...
+ -- If we inline g's wrapper, f looks big, and doesn't get inlined
+ -- into h; if we inline f first, while it looks small, then g's
+ -- wrapper will get inlined later anyway. To avoid this nasty
+ -- ordering difference, we make (case a of (x,y) -> ...) look free.
+ size_up (Case (Var v) _ [alt])
+ | v `elem` top_args
+ = size_up_alt alt `addSize` SizeIs 0# (unitBag (v, 1)) 0#
+ -- Good to inline if an arg is scrutinised, because
+ -- that may eliminate allocation in the caller
+ -- And it eliminates the case itself
+ | otherwise
+ = size_up_alt alt
+
+ -- Scrutinising one of the argument variables,
+ -- with more than one alternative
+ size_up (Case (Var v) _ alts)
+ | v `elem` top_args
+ = alts_size (foldr addSize sizeOne alt_sizes) -- The 1 is for the scrutinee
+ (foldr1 maxSize alt_sizes)
+ where
+ v_in_args = v `elem` top_args
+ alt_sizes = map size_up_alt alts
+
+ alts_size (SizeIs tot tot_disc tot_scrut) -- Size of all alternatives
+ (SizeIs max max_disc max_scrut) -- Size of biggest alternative
+ = SizeIs tot (unitBag (v, I# (1# +# tot -# max)) `unionBags` max_disc) max_scrut
+ -- If the variable is known, we produce a discount that
+ -- will take us back to 'max', the size of rh largest alternative
+ -- The 1+ is a little discount for reduced allocation in the caller
+
+ alts_size tot_size _ = tot_size
+
+
+ size_up (Case e _ alts) = nukeScrutDiscount (size_up e) `addSize`
+ foldr (addSize . size_up_alt) sizeZero alts
+ -- We don't charge for the case itself
+ -- It's a strict thing, and the price of the call
+ -- is paid by scrut. Also consider
+ -- case f x of DEFAULT -> e
+ -- This is just ';'! Don't charge for it.