| ... |
... |
@@ -335,6 +335,10 @@ isValFun :: CoreExpr -> Bool |
|
335
|
335
|
-- one top-level value lambda
|
|
336
|
336
|
isValFun (Lam b e) | isRuntimeVar b = True
|
|
337
|
337
|
| otherwise = isValFun e
|
|
|
338
|
+-- A tick can be code which *can* change the runtime semantics here.
|
|
|
339
|
+-- But we want to ignore it anyway. See Note [Ticks and Cast should not impact unfolding guidance]
|
|
|
340
|
+isValFun (Tick _t e) = isValFun e
|
|
|
341
|
+isValFun (Cast e _co) = isValFun e
|
|
338
|
342
|
isValFun _ = False
|
|
339
|
343
|
|
|
340
|
344
|
calcUnfoldingGuidance
|
| ... |
... |
@@ -669,6 +673,11 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr |
|
669
|
673
|
is_inline_scrut (Var v) =
|
|
670
|
674
|
isUnliftedType (idType v)
|
|
671
|
675
|
-- isUnliftedType is OK here: scrutinees have a fixed RuntimeRep (search for FRRCase)
|
|
|
676
|
+ -- Even if this makes the check technically wrong we want to
|
|
|
677
|
+ -- look through ticks here.
|
|
|
678
|
+ -- See Note [Ticks and Cast should not impact unfolding guidance]
|
|
|
679
|
+ is_inline_scrut (Tick _t e) = is_inline_scrut e
|
|
|
680
|
+ is_inline_scrut (Cast e _co) = is_inline_scrut e
|
|
672
|
681
|
is_inline_scrut scrut
|
|
673
|
682
|
| (Var f, _) <- collectArgs scrut
|
|
674
|
683
|
= case idDetails f of
|
| ... |
... |
@@ -709,7 +718,7 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr |
|
709
|
718
|
FCallId _ -> sizeN (callSize (length val_args) voids)
|
|
710
|
719
|
DataConWorkId dc -> conSize dc (length val_args)
|
|
711
|
720
|
PrimOpId op _ -> primOpSize op (length val_args)
|
|
712
|
|
- ClassOpId cls _ -> classOpSize opts cls top_args val_args
|
|
|
721
|
+ ClassOpId cls _ -> classOpSize opts cls top_args val_args voids
|
|
713
|
722
|
_ | fun `hasKey` buildIdKey -> buildSize
|
|
714
|
723
|
| fun `hasKey` augmentIdKey -> augmentSize
|
|
715
|
724
|
| otherwise -> funSize opts top_args fun (length val_args) voids
|
| ... |
... |
@@ -761,9 +770,11 @@ sizeExpr opts !bOMB_OUT_SIZE top_args expr |
|
761
|
770
|
-- and typePrimRep will crash
|
|
762
|
771
|
isZeroBitId id = not (isJoinId id) && isZeroBitTy (idType id)
|
|
763
|
772
|
|
|
764
|
|
- isZeroBitExpr (Var id) = isZeroBitId id
|
|
765
|
|
- isZeroBitExpr (Tick _ e) = isZeroBitExpr e
|
|
766
|
|
- isZeroBitExpr _ = False
|
|
|
773
|
+ -- [Ticks and Cast should not impact unfolding guidance]
|
|
|
774
|
+ isZeroBitExpr (Var id) = isZeroBitId id
|
|
|
775
|
+ isZeroBitExpr (Tick _t e) = isZeroBitExpr e
|
|
|
776
|
+ isZeroBitExpr (Cast e _co) = isZeroBitExpr e
|
|
|
777
|
+ isZeroBitExpr _ = False
|
|
767
|
778
|
|
|
768
|
779
|
-- | Finds a nominal size of a string literal.
|
|
769
|
780
|
litSize :: Literal -> Int
|
| ... |
... |
@@ -777,21 +788,29 @@ litSize _other = 0 -- Must match size of nullary constructors |
|
777
|
788
|
-- Key point: if x |-> 4, then x must inline unconditionally
|
|
778
|
789
|
-- (eg via case binding)
|
|
779
|
790
|
|
|
780
|
|
-classOpSize :: UnfoldingOpts -> Class -> [Id] -> [CoreExpr] -> ExprSize
|
|
|
791
|
+classOpSize :: UnfoldingOpts -> Class -> [Id] -> [CoreExpr] -> Int -> ExprSize
|
|
781
|
792
|
-- See (IA1) in Note [Interesting arguments] in GHC.Core.Opt.Simplify.Utils
|
|
782
|
|
-classOpSize _opts _cls _top_args []
|
|
|
793
|
+classOpSize _opts _cls _top_args [] _voids
|
|
783
|
794
|
= sizeZero -- A non-applied classop
|
|
784
|
|
-classOpSize opts cls top_args (dict_arg:other_val_args)
|
|
785
|
|
- = SizeIs size (arg_discount dict_arg) 0
|
|
|
795
|
+classOpSize opts cls top_args (dict_arg:other_val_args) voids
|
|
|
796
|
+ = SizeIs size dict_arg_discount 0
|
|
786
|
797
|
where
|
|
787
|
|
- size | isUnaryClass cls = 0 -- See (UCM4) in Note [Unary class magic] in GHC.Core.TyCon
|
|
788
|
|
- | otherwise = 20 + (10 * length other_val_args)
|
|
|
798
|
+ -- See (UCM4) in Note [Unary class magic] in GHC.Core.TyCon
|
|
|
799
|
+ op_app_size = if isUnaryClass cls then 0 else 20
|
|
|
800
|
+
|
|
|
801
|
+ -- Size penalty for applying the extracted class method to it's
|
|
|
802
|
+ -- arguments.
|
|
|
803
|
+ method_app_size = callSize (length other_val_args) voids
|
|
|
804
|
+
|
|
|
805
|
+ size = op_app_size + method_app_size
|
|
789
|
806
|
|
|
790
|
807
|
-- If the class op is scrutinising a lambda bound dictionary then
|
|
791
|
808
|
-- give it a discount, to encourage the inlining of this function
|
|
792
|
|
- arg_discount (Cast arg _co) = arg_discount arg
|
|
793
|
|
- arg_discount (Var dict) | dict `elem` top_args = unitBag (dict, dict_discount)
|
|
794
|
|
- arg_discount _ = emptyBag
|
|
|
809
|
+ dict_arg_discount = case getIdFromTrivialExpr_maybe dict_arg of
|
|
|
810
|
+ Nothing -> emptyBag
|
|
|
811
|
+ Just var
|
|
|
812
|
+ | var `elem` top_args -> unitBag (var, dict_discount)
|
|
|
813
|
+ | otherwise -> emptyBag
|
|
795
|
814
|
|
|
796
|
815
|
-- If we have (class-op d arg1 .. argn) then it's super-good to inline
|
|
797
|
816
|
-- to expose `d`; not only can we do the dictionary selection
|
| ... |
... |
@@ -1051,6 +1070,23 @@ In a function application (f a b) |
|
1051
|
1070
|
get a saturated application)
|
|
1052
|
1071
|
|
|
1053
|
1072
|
Code for manipulating sizes
|
|
|
1073
|
+
|
|
|
1074
|
+Note [Ticks and Cast should not impact unfolding guidance]
|
|
|
1075
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
1076
|
+We want to ignore ticks and casts when
|
|
|
1077
|
+computing unfolding guidance. The reason is simple:
|
|
|
1078
|
+
|
|
|
1079
|
+We want inlining to be robust if a user changes a type alias
|
|
|
1080
|
+to a newtype, if the code is otherwise the same.
|
|
|
1081
|
+
|
|
|
1082
|
+Similarly we want inlining to behave the same for a core expression
|
|
|
1083
|
+(<tick> e) as it does for `e`.
|
|
|
1084
|
+This is **independent** of the kind of tick we are dealing with.
|
|
|
1085
|
+Even for ticks that represent code at runtime we generally want
|
|
|
1086
|
+to inline as-if no tick is present. This way profiled code will
|
|
|
1087
|
+be closer to non-profiled code, which leads to more accurate profiles.
|
|
|
1088
|
+
|
|
|
1089
|
+So we take care to look through Cast/Ticks wherever possible.
|
|
1054
|
1090
|
-}
|
|
1055
|
1091
|
|
|
1056
|
1092
|
-- | The size of a candidate expression for unfolding
|