diff options
author | Simon Marlow <marlowsd@gmail.com> | 2016-02-10 09:19:34 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2016-02-11 14:57:00 +0000 |
commit | 51a33924fc118d9b6c1db556c75c0d010ef95e18 (patch) | |
tree | 14001a4bfd50008dcc2b0ac78c1266411e6f9073 /compiler | |
parent | 023bf8d402652f63de9622e00276cb7b6cb4b261 (diff) | |
download | haskell-51a33924fc118d9b6c1db556c75c0d010ef95e18.tar.gz |
sizeExpr: fix a bug in the size calculation
There were two bugs here:
* We weren't ignoring Cast in size_up_app
* An application of a non-variable wasn't being charged correct
The result was that some things looked too cheap. In my case I had
things like
((f x) `cast` ...) y
which was given size 21 instead of 30, and this had knock-on effects
elsewhere that caused some large code bloat.
Test Plan:
* nofib runs (todo)
* validate
Reviewers: simonpj, austin, bgamari, erikd
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1900
GHC Trac Issues: #11564
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/coreSyn/CoreUnfold.hs | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/compiler/coreSyn/CoreUnfold.hs b/compiler/coreSyn/CoreUnfold.hs index 48cdb5e5f6..a03b427f84 100644 --- a/compiler/coreSyn/CoreUnfold.hs +++ b/compiler/coreSyn/CoreUnfold.hs @@ -578,13 +578,18 @@ sizeExpr dflags bOMB_OUT_SIZE top_args expr size_up_app fun (arg:args) voids size_up_app (Var fun) args voids = size_up_call fun args voids size_up_app (Tick _ expr) args voids = size_up_app expr args voids - size_up_app other args voids = size_up other `addSizeN` (length args - voids) + size_up_app (Cast expr _) args voids = size_up_app expr args voids + size_up_app other args voids = size_up other `addSizeN` + callSize (length args) voids + -- if the lhs is not an App or a Var, or an invisible thing like a + -- Tick or Cast, then we should charge for a complete call plus the + -- size of the lhs itself. ------------ size_up_call :: Id -> [CoreExpr] -> Int -> ExprSize size_up_call fun val_args voids = case idDetails fun of - FCallId _ -> sizeN (10 * (1 + length val_args)) + FCallId _ -> sizeN (callSize (length val_args) voids) DataConWorkId dc -> conSize dc (length val_args) PrimOpId op -> primOpSize op (length val_args) ClassOpId _ -> classOpSize dflags top_args val_args @@ -657,6 +662,13 @@ classOpSize dflags top_args (arg1 : other_args) -> unitBag (dict, ufDictDiscount dflags) _other -> emptyBag +-- | The size of a function call +callSize + :: Int -- ^ number of value args + -> Int -- ^ number of value args that are void + -> Int +callSize n_val_args voids = 10 * (1 + n_val_args - voids) + funSize :: DynFlags -> [Id] -> Id -> Int -> Int -> ExprSize -- Size for functions that are not constructors or primops -- Note [Function applications] @@ -667,7 +679,7 @@ funSize dflags top_args fun n_val_args voids where some_val_args = n_val_args > 0 - size | some_val_args = 10 * (1 + n_val_args - voids) + size | some_val_args = callSize n_val_args voids | otherwise = 0 -- The 1+ is for the function itself -- Add 1 for each non-trivial arg; |