[commit: ghc] master: Optimise (case tagToEnum# x of ..) as in Trac #8317 (62c4058)
git at git.haskell.org
git at git.haskell.org
Wed Sep 18 14:07:04 CEST 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/62c405854afbeb6dabdaf5c737a2d7f625a2b3cb/ghc
>---------------------------------------------------------------
commit 62c405854afbeb6dabdaf5c737a2d7f625a2b3cb
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Tue Sep 17 22:02:27 2013 +0100
Optimise (case tagToEnum# x of ..) as in Trac #8317
See Note [Optimising tagToEnum#] in Simplify
>---------------------------------------------------------------
62c405854afbeb6dabdaf5c737a2d7f625a2b3cb
compiler/simplCore/Simplify.lhs | 43 ++++++++++++++++++++++++++++++++++++---
1 file changed, 40 insertions(+), 3 deletions(-)
diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs
index d006f7f..a88d943 100644
--- a/compiler/simplCore/Simplify.lhs
+++ b/compiler/simplCore/Simplify.lhs
@@ -14,7 +14,7 @@ import Type hiding ( substTy, extendTvSubst, substTyVar )
import SimplEnv
import SimplUtils
import FamInstEnv ( FamInstEnv )
-import Literal ( litIsLifted )
+import Literal ( litIsLifted, mkMachInt )
import Id
import MkId ( seqId, realWorldPrimId )
import MkCore ( mkImpossibleExpr, castBottomExpr )
@@ -23,7 +23,9 @@ import Name ( mkSystemVarName, isExternalName )
import Coercion hiding ( substCo, substTy, substCoVar, extendTvSubst )
import OptCoercion ( optCoercion )
import FamInstEnv ( topNormaliseType )
-import DataCon ( DataCon, dataConWorkId, dataConRepStrictness, isMarkedStrict )
+import DataCon ( DataCon, dataConWorkId, dataConRepStrictness
+ , isMarkedStrict, dataConTyCon, dataConTag, fIRST_TAG )
+import TyCon ( isEnumerationTyCon )
import CoreMonad ( Tick(..), SimplifierMode(..) )
import CoreSyn
import Demand ( StrictSig(..), dmdTypeDepth )
@@ -31,11 +33,13 @@ import PprCore ( pprParendExpr, pprCoreExpr )
import CoreUnfold
import CoreUtils
import CoreArity
+import PrimOp ( tagToEnumKey )
import Rules ( lookupRule, getRules )
-import TysPrim ( realWorldStatePrimTy )
+import TysPrim ( realWorldStatePrimTy, intPrimTy )
import BasicTypes ( TopLevelFlag(..), isTopLevel, RecFlag(..) )
import MonadUtils ( foldlM, mapAccumLM, liftIO )
import Maybes ( orElse )
+import Unique ( hasKey )
import Control.Monad
import Data.List ( mapAccumL )
import Outputable
@@ -1561,6 +1565,27 @@ tryRules :: SimplEnv -> [CoreRule]
tryRules env rules fn args call_cont
| null rules
= return Nothing
+
+ | fn `hasKey` tagToEnumKey -- See Note [Optimising tagToEnum#]
+ , [_type_arg, val_arg] <- args
+ , Select dup bndr ((_,[],rhs1) : rest_alts) se cont <- call_cont
+ , isDeadBinder bndr
+ = do { dflags <- getDynFlags
+ ; let enum_to_tag :: CoreAlt -> CoreAlt
+ -- Takes K -> e into tagK# -> e
+ -- where tagK# is the tag of constructor K
+ enum_to_tag (DataAlt con, [], rhs)
+ = ASSERT( isEnumerationTyCon (dataConTyCon con) )
+ (LitAlt tag, [], rhs)
+ where
+ tag = mkMachInt dflags (toInteger (dataConTag con - fIRST_TAG))
+ enum_to_tag alt = pprPanic "tryRules: tagToEnum" (ppr alt)
+
+ new_alts = (DEFAULT, [], rhs1) : map enum_to_tag rest_alts
+ new_bndr = setIdType bndr intPrimTy
+ -- The binder is dead, but should have the right type
+ ; return (Just (val_arg, Select dup new_bndr new_alts se cont)) }
+
| otherwise
= do { dflags <- getDynFlags
; case lookupRule dflags (getUnfoldingInRuleMatch env) (activeRule env)
@@ -1594,6 +1619,18 @@ tryRules env rules fn args call_cont
sep [text hdr, nest 4 details]
\end{code}
+Note [Optimising tagToEnum#]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We want to transform
+ case tagToEnum# x of ==> case x of
+ True -> e1 DEFAULT -> e1
+ False -> e2 0# -> e2
+
+thereby getting rid of the tagToEnum# altogether. If there was a DEFAULT
+alternative we retain it (remember it comes first). If not the case must
+be exhaustive, and we reflect that in the transformed version by adding
+a DEFAULT. Otherwise Lint complains that the new case is not exhaustive.
+
Note [Rules for recursive functions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You might think that we shouldn't apply rules for a loop breaker:
More information about the ghc-commits
mailing list