Commit b71760aa authored by simonpj@microsoft.com's avatar simonpj@microsoft.com
Browse files

Adjust inlining heursitics

This patch is the result of a long series of nofib-based experiments
to improve GHC's inlining heuristics.

In the end, I'm not sure how worthwhile it all was: I only got a 
   1% decrease in code size
   1% decrease in allocation
and I don't trust the runtime statistics enough to quote.

Still, in doing all this I tidied up the code quite a bit, and 
I understand it much better now, so I'm going to commit it.

The main changes are in CoreUnfold, which has lots of new comments.
Other changes:

  - litSize moves from Literal to CoreUnfold
  - interestingArg moves from SimplUtils to CoreUnfold
  - the default unfolding threshold (in StaticFlags) 
      reduces from 8 to 6 (since the size calculation 
      has changed a bit)
parent 9060e51e
...@@ -24,7 +24,6 @@ module Literal ...@@ -24,7 +24,6 @@ module Literal
, mkMachChar, mkMachString , mkMachChar, mkMachString
-- ** Operations on Literals -- ** Operations on Literals
, litSize
, literalType , literalType
, hashLiteral , hashLiteral
...@@ -332,15 +331,6 @@ litFitsInChar (MachInt i) ...@@ -332,15 +331,6 @@ litFitsInChar (MachInt i)
= fromInteger i <= ord minBound = fromInteger i <= ord minBound
&& fromInteger i >= ord maxBound && fromInteger i >= ord maxBound
litFitsInChar _ = False litFitsInChar _ = False
-- | Finds a nominal size of a string literal. Every literal has size at least 1
litSize :: Literal -> Int
-- Used by CoreUnfold.sizeExpr
litSize (MachStr str) = 1 + ((lengthFS str + 3) `div` 4)
-- If size could be 0 then @f "x"@ might be too small
-- [Sept03: make literal strings a bit bigger to avoid fruitless
-- duplication of little strings]
litSize _other = 1
\end{code} \end{code}
Types Types
......
This diff is collapsed.
...@@ -251,7 +251,7 @@ opt_SimplExcessPrecision = lookUp (fsLit "-fexcess-precision") ...@@ -251,7 +251,7 @@ opt_SimplExcessPrecision = lookUp (fsLit "-fexcess-precision")
opt_UF_CreationThreshold :: Int opt_UF_CreationThreshold :: Int
opt_UF_CreationThreshold = lookup_def_int "-funfolding-creation-threshold" (45::Int) opt_UF_CreationThreshold = lookup_def_int "-funfolding-creation-threshold" (45::Int)
opt_UF_UseThreshold :: Int opt_UF_UseThreshold :: Int
opt_UF_UseThreshold = lookup_def_int "-funfolding-use-threshold" (8::Int) -- Discounts can be big opt_UF_UseThreshold = lookup_def_int "-funfolding-use-threshold" (6::Int) -- Discounts can be big
opt_UF_FunAppDiscount :: Int opt_UF_FunAppDiscount :: Int
opt_UF_FunAppDiscount = lookup_def_int "-funfolding-fun-discount" (6::Int) -- It's great to inline a fn opt_UF_FunAppDiscount = lookup_def_int "-funfolding-fun-discount" (6::Int) -- It's great to inline a fn
opt_UF_KeenessFactor :: Float opt_UF_KeenessFactor :: Float
......
...@@ -246,42 +246,8 @@ splitInlineCont _ = Nothing ...@@ -246,42 +246,8 @@ splitInlineCont _ = Nothing
\end{code} \end{code}
\begin{code} Note [Interesting call context]
interestingArg :: OutExpr -> Bool ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- An argument is interesting if it has *some* structure
-- We are here trying to avoid unfolding a function that
-- is applied only to variables that have no unfolding
-- (i.e. they are probably lambda bound): f x y z
-- There is little point in inlining f here.
interestingArg (Var v) = hasSomeUnfolding (idUnfolding v)
-- Was: isValueUnfolding (idUnfolding v')
-- But that seems over-pessimistic
|| isDataConWorkId v
-- This accounts for an argument like
-- () or [], which is definitely interesting
interestingArg (Type _) = False
interestingArg (App fn (Type _)) = interestingArg fn
interestingArg (Note _ a) = interestingArg a
-- Idea (from Sam B); I'm not sure if it's a good idea, so commented out for now
-- interestingArg expr | isUnLiftedType (exprType expr)
-- -- Unlifted args are only ever interesting if we know what they are
-- = case expr of
-- Lit lit -> True
-- _ -> False
interestingArg _ = True
-- Consider let x = 3 in f x
-- The substitution will contain (x -> ContEx 3), and we want to
-- to say that x is an interesting argument.
-- But consider also (\x. f x y) y
-- The substitution will contain (x -> ContEx y), and we want to say
-- that x is not interesting (assuming y has no unfolding)
\end{code}
Comment about interestingCallContext
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We want to avoid inlining an expression where there can't possibly be We want to avoid inlining an expression where there can't possibly be
any gain, such as in an argument position. Hence, if the continuation any gain, such as in an argument position. Hence, if the continuation
is interesting (eg. a case scrutinee, application etc.) then we is interesting (eg. a case scrutinee, application etc.) then we
...@@ -316,6 +282,7 @@ default case. ...@@ -316,6 +282,7 @@ default case.
\begin{code} \begin{code}
interestingCallContext :: SimplCont -> CallCtxt interestingCallContext :: SimplCont -> CallCtxt
-- See Note [Interesting call context]
interestingCallContext cont interestingCallContext cont
= interesting cont = interesting cont
where where
...@@ -354,7 +321,7 @@ interestingCallContext cont ...@@ -354,7 +321,7 @@ interestingCallContext cont
------------------- -------------------
mkArgInfo :: Id mkArgInfo :: Id
-> Int -- Number of value args -> Int -- Number of value args
-> SimplCont -- Context of the cal -> SimplCont -- Context of the call
-> ArgInfo -> ArgInfo
mkArgInfo fun n_val_args call_cont mkArgInfo fun n_val_args call_cont
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment