[commit: ghc] wip/T7994-calledArity: Stop fixpointing when below exprArity (849bd01)
git at git.haskell.org
git at git.haskell.org
Wed Jan 29 15:18:03 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/T7994-calledArity
Link : http://ghc.haskell.org/trac/ghc/changeset/849bd0146eaec36b88f80b7cb41cefa88607b5f3/ghc
>---------------------------------------------------------------
commit 849bd0146eaec36b88f80b7cb41cefa88607b5f3
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Wed Jan 29 15:10:58 2014 +0000
Stop fixpointing when below exprArity
>---------------------------------------------------------------
849bd0146eaec36b88f80b7cb41cefa88607b5f3
compiler/simplCore/CallArity.hs | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/compiler/simplCore/CallArity.hs b/compiler/simplCore/CallArity.hs
index 42969a4..c9ba91a 100644
--- a/compiler/simplCore/CallArity.hs
+++ b/compiler/simplCore/CallArity.hs
@@ -17,8 +17,7 @@ import Id
import CoreArity
import Control.Arrow ( second )
-import Data.Maybe ( fromMaybe, isJust )
-
+import Data.Maybe ( isJust )
{-
@@ -176,7 +175,7 @@ callArityAnal arity int (Let (Rec [(v,rhs)]) e)
| Just n <- rhs_arity
= let (ae_rhs, rhs_arity', rhs') = callArityFix n int_body v rhs
final_ae = ae_rhs `lubEnv` ae_body'
- v' = v `setIdCallArity` fromMaybe 0 rhs_arity'
+ v' = v `setIdCallArity` rhs_arity'
in -- pprTrace "callArityAnal:LetRecTailCall"
-- (vcat [ppr v, ppr arity, ppr n, ppr rhs_arity', ppr final_ae ])
(final_ae, Let (Rec [(v',rhs')]) e')
@@ -229,24 +228,35 @@ callArityAnal arity int (Case scrut bndr ty alts)
in (ae, (dc, bndrs, e'))
alt_ae = foldl lubEnv emptyVarEnv alt_aes
(scrut_ae, scrut') = callArityAnal 0 int scrut
+ -- See Note [Case and App: Which side to take?]
final_ae = scrut_ae `useBetterOf` alt_ae
-callArityFix :: Arity -> VarSet -> Id -> CoreExpr -> (CallArityEnv, Maybe Arity, CoreExpr)
+callArityFix :: Arity -> VarSet -> Id -> CoreExpr -> (CallArityEnv, Arity, CoreExpr)
callArityFix arity int v e
- | Nothing <- new_arity
- -- Not tail recusive, rerun with arity 0 and bail out
- -- (Or not recursive at all, but that was hopefully handled by the simplifier before)
- = let (ae, e') = callArityAnal 0 int e
- in (forgetTailCalls ae `delVarEnv` v, Nothing, e')
- | Just n <- new_arity, n < arity
- -- Retry
- = callArityFix n int v e
+
+ | arity <= min_arity
+ -- The incoming arity is already lower than the exprArity, so we can
+ -- ignore the arity coming from the RHS
+ = (ae `delVarEnv` v, 0, e')
+
| otherwise
- -- RHS calls itself with at least as many arguments as the body of the let
- = (ae `delVarEnv` v, new_arity, e')
+ = case new_arity of
+ -- Not nicely recursive, rerun with arity 0
+ -- (which will do at most one iteration, see above)
+ -- (Or not recursive at all, but that was hopefully handled by the simplifier before)
+ Nothing -> callArityFix 0 int v e
+
+ Just n -> if n < arity
+ -- RHS puts a lower arity on itself, but still a nice call, so try with that
+ then callArityFix n int v e
+
+ -- RHS calls itself with at least as many arguments as the body of
+ -- the let: Great!
+ else (ae `delVarEnv` v, n, e')
where
(ae, e') = callArityAnal arity int e
new_arity = lookupWithDefaultVarEnv ae Nothing v
+ min_arity = exprArity e
anyGoodCalls :: VarEnv (Maybe Arity) -> Bool
More information about the ghc-commits
mailing list