{-# LANGUAGE CPP #-}
module CoreUtils (
mkCast,
mkTick, mkTicks, mkTickNoHNF, tickHNFArgs,
bindNonRec, needsCaseBinding,
mkAltExpr,
findDefault, addDefault, findAlt, isDefaultAlt,
mergeAlts, trimConArgs,
filterAlts, combineIdenticalAlts, refineDefaultAlt,
exprType, coreAltType, coreAltsType, isExprLevPoly,
exprIsDupable, exprIsTrivial, getIdFromTrivialExpr, exprIsBottom,
getIdFromTrivialExpr_maybe,
exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun,
exprIsHNF, exprOkForSpeculation, exprOkForSideEffects, exprIsWorkFree,
exprIsBig, exprIsConLike,
rhsIsStatic, isCheapApp, isExpandableApp,
exprIsTickedString, exprIsTickedString_maybe,
exprIsTopLevelBindable,
altsAreExhaustive,
cheapEqExpr, cheapEqExpr', eqExpr,
diffExpr, diffBinds,
tryEtaReduce,
exprToType, exprToCoercion_maybe,
applyTypeToArgs, applyTypeToArg,
dataConRepInstPat, dataConRepFSInstPat,
isEmptyTy,
stripTicksTop, stripTicksTopE, stripTicksTopT,
stripTicksE, stripTicksT,
collectMakeStaticArgs,
isJoinBind
) where
#include "HsVersions.h"
import GhcPrelude
import CoreSyn
import PrelNames ( makeStaticName )
import PprCore
import CoreFVs( exprFreeVars )
import Var
import SrcLoc
import VarEnv
import VarSet
import Name
import Literal
import DataCon
import PrimOp
import Id
import IdInfo
import PrelNames( absentErrorIdKey )
import Type
import TyCoRep( TyCoBinder(..), TyBinder )
import Coercion
import TyCon
import Unique
import Outputable
import TysPrim
import DynFlags
import FastString
import Maybes
import ListSetOps ( minusList )
import BasicTypes ( Arity, isConLike )
import Platform
import Util
import Pair
import Data.ByteString ( ByteString )
import Data.Function ( on )
import Data.List
import Data.Ord ( comparing )
import OrdList
import qualified Data.Set as Set
import UniqSet
exprType :: CoreExpr -> Type
exprType :: CoreExpr -> Type
exprType (Var var :: Id
var) = Id -> Type
idType Id
var
exprType (Lit lit :: Literal
lit) = Literal -> Type
literalType Literal
lit
exprType (Coercion co :: Coercion
co) = Coercion -> Type
coercionType Coercion
co
exprType (Let bind :: Bind Id
bind body :: CoreExpr
body)
| NonRec tv :: Id
tv rhs :: CoreExpr
rhs <- Bind Id
bind
, Type ty :: Type
ty <- CoreExpr
rhs = [Id] -> [Type] -> Type -> Type
substTyWithUnchecked [Id
tv] [Type
ty] (CoreExpr -> Type
exprType CoreExpr
body)
| Bool
otherwise = CoreExpr -> Type
exprType CoreExpr
body
exprType (Case _ _ ty :: Type
ty _) = Type
ty
exprType (Cast _ co :: Coercion
co) = Pair Type -> Type
forall a. Pair a -> a
pSnd (Coercion -> Pair Type
coercionKind Coercion
co)
exprType (Tick _ e :: CoreExpr
e) = CoreExpr -> Type
exprType CoreExpr
e
exprType (Lam binder :: Id
binder expr :: CoreExpr
expr) = Id -> Type -> Type
mkLamType Id
binder (CoreExpr -> Type
exprType CoreExpr
expr)
exprType e :: CoreExpr
e@(App _ _)
= case CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
e of
(fun :: CoreExpr
fun, args :: [CoreExpr]
args) -> CoreExpr -> Type -> [CoreExpr] -> Type
applyTypeToArgs CoreExpr
e (CoreExpr -> Type
exprType CoreExpr
fun) [CoreExpr]
args
exprType other :: CoreExpr
other = String -> SDoc -> Type -> Type
forall a. String -> SDoc -> a -> a
pprTrace "exprType" (CoreExpr -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
other) Type
alphaTy
coreAltType :: CoreAlt -> Type
coreAltType :: CoreAlt -> Type
coreAltType alt :: CoreAlt
alt@(_,bs :: [Id]
bs,rhs :: CoreExpr
rhs)
= case [Id] -> Type -> Maybe Type
occCheckExpand [Id]
bs Type
rhs_ty of
Just ty :: Type
ty -> Type
ty
Nothing -> String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic "coreAltType" (CoreAlt -> SDoc
forall a. OutputableBndr a => (AltCon, [a], Expr a) -> SDoc
pprCoreAlt CoreAlt
alt SDoc -> SDoc -> SDoc
$$ Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
rhs_ty)
where
rhs_ty :: Type
rhs_ty = CoreExpr -> Type
exprType CoreExpr
rhs
coreAltsType :: [CoreAlt] -> Type
coreAltsType :: [CoreAlt] -> Type
coreAltsType (alt :: CoreAlt
alt:_) = CoreAlt -> Type
coreAltType CoreAlt
alt
coreAltsType [] = String -> Type
forall a. String -> a
panic "corAltsType"
isExprLevPoly :: CoreExpr -> Bool
isExprLevPoly :: CoreExpr -> Bool
isExprLevPoly = CoreExpr -> Bool
go
where
go :: CoreExpr -> Bool
go (Var _) = Bool
False
go (Lit _) = Bool
False
go e :: CoreExpr
e@(App f :: CoreExpr
f _) | Bool -> Bool
not (CoreExpr -> Bool
forall b. OutputableBndr b => Expr b -> Bool
go_app CoreExpr
f) = Bool
False
| Bool
otherwise = CoreExpr -> Bool
check_type CoreExpr
e
go (Lam _ _) = Bool
False
go (Let _ e :: CoreExpr
e) = CoreExpr -> Bool
go CoreExpr
e
go e :: CoreExpr
e@(Case {}) = CoreExpr -> Bool
check_type CoreExpr
e
go e :: CoreExpr
e@(Cast {}) = CoreExpr -> Bool
check_type CoreExpr
e
go (Tick _ e :: CoreExpr
e) = CoreExpr -> Bool
go CoreExpr
e
go e :: CoreExpr
e@(Type {}) = String -> SDoc -> Bool
forall a. HasCallStack => String -> SDoc -> a
pprPanic "isExprLevPoly ty" (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e)
go (Coercion {}) = Bool
False
check_type :: CoreExpr -> Bool
check_type = Type -> Bool
isTypeLevPoly (Type -> Bool) -> (CoreExpr -> Type) -> CoreExpr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreExpr -> Type
exprType
go_app :: Expr b -> Bool
go_app (Var id :: Id
id) = Bool -> Bool
not (Id -> Bool
isNeverLevPolyId Id
id)
go_app (Lit _) = Bool
False
go_app (App f :: Expr b
f _) = Expr b -> Bool
go_app Expr b
f
go_app (Lam _ e :: Expr b
e) = Expr b -> Bool
go_app Expr b
e
go_app (Let _ e :: Expr b
e) = Expr b -> Bool
go_app Expr b
e
go_app (Case _ _ ty :: Type
ty _) = Type -> Bool
resultIsLevPoly Type
ty
go_app (Cast _ co :: Coercion
co) = Type -> Bool
resultIsLevPoly (Pair Type -> Type
forall a. Pair a -> a
pSnd (Pair Type -> Type) -> Pair Type -> Type
forall a b. (a -> b) -> a -> b
$ Coercion -> Pair Type
coercionKind Coercion
co)
go_app (Tick _ e :: Expr b
e) = Expr b -> Bool
go_app Expr b
e
go_app e :: Expr b
e@(Type {}) = String -> SDoc -> Bool
forall a. HasCallStack => String -> SDoc -> a
pprPanic "isExprLevPoly app ty" (Expr b -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr b
e)
go_app e :: Expr b
e@(Coercion {}) = String -> SDoc -> Bool
forall a. HasCallStack => String -> SDoc -> a
pprPanic "isExprLevPoly app co" (Expr b -> SDoc
forall a. Outputable a => a -> SDoc
ppr Expr b
e)
applyTypeToArgs :: CoreExpr -> Type -> [CoreExpr] -> Type
applyTypeToArgs :: CoreExpr -> Type -> [CoreExpr] -> Type
applyTypeToArgs e :: CoreExpr
e op_ty :: Type
op_ty args :: [CoreExpr]
args
= Type -> [CoreExpr] -> Type
forall b. Type -> [Expr b] -> Type
go Type
op_ty [CoreExpr]
args
where
go :: Type -> [Expr b] -> Type
go op_ty :: Type
op_ty [] = Type
op_ty
go op_ty :: Type
op_ty (Type ty :: Type
ty : args :: [Expr b]
args) = Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty [Type
ty] [Expr b]
args
go op_ty :: Type
op_ty (Coercion co :: Coercion
co : args :: [Expr b]
args) = Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty [Coercion -> Type
mkCoercionTy Coercion
co] [Expr b]
args
go op_ty :: Type
op_ty (_ : args :: [Expr b]
args) | Just (_, res_ty :: Type
res_ty) <- Type -> Maybe (Type, Type)
splitFunTy_maybe Type
op_ty
= Type -> [Expr b] -> Type
go Type
res_ty [Expr b]
args
go _ _ = String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic "applyTypeToArgs" SDoc
panic_msg
go_ty_args :: Type -> [Type] -> [Expr b] -> Type
go_ty_args op_ty :: Type
op_ty rev_tys :: [Type]
rev_tys (Type ty :: Type
ty : args :: [Expr b]
args)
= Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty (Type
tyType -> [Type] -> [Type]
forall a. a -> [a] -> [a]
:[Type]
rev_tys) [Expr b]
args
go_ty_args op_ty :: Type
op_ty rev_tys :: [Type]
rev_tys (Coercion co :: Coercion
co : args :: [Expr b]
args)
= Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty (Coercion -> Type
mkCoercionTy Coercion
co Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
rev_tys) [Expr b]
args
go_ty_args op_ty :: Type
op_ty rev_tys :: [Type]
rev_tys args :: [Expr b]
args
= Type -> [Expr b] -> Type
go (HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys Type
op_ty ([Type] -> [Type]
forall a. [a] -> [a]
reverse [Type]
rev_tys)) [Expr b]
args
panic_msg :: SDoc
panic_msg = [SDoc] -> SDoc
vcat [ String -> SDoc
text "Expression:" SDoc -> SDoc -> SDoc
<+> CoreExpr -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
e
, String -> SDoc
text "Type:" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
op_ty
, String -> SDoc
text "Args:" SDoc -> SDoc -> SDoc
<+> [CoreExpr] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreExpr]
args ]
mkCast :: CoreExpr -> CoercionR -> CoreExpr
mkCast :: CoreExpr -> Coercion -> CoreExpr
mkCast e :: CoreExpr
e co :: Coercion
co
| ASSERT2( coercionRole co == Representational
, text "coercion" <+> ppr co <+> ptext (sLit "passed to mkCast")
<+> ppr e <+> text "has wrong role" <+> ppr (coercionRole co) )
Coercion -> Bool
isReflCo Coercion
co
= CoreExpr
e
mkCast (Coercion e_co :: Coercion
e_co) co :: Coercion
co
| Type -> Bool
isCoVarType (Pair Type -> Type
forall a. Pair a -> a
pSnd (Coercion -> Pair Type
coercionKind Coercion
co))
= Coercion -> CoreExpr
forall b. Coercion -> Expr b
Coercion (Coercion -> Coercion -> Coercion
mkCoCast Coercion
e_co Coercion
co)
mkCast (Cast expr :: CoreExpr
expr co2 :: Coercion
co2) co :: Coercion
co
= WARN(let { Pair from_ty _to_ty = coercionKind co;
Pair _from_ty2 to_ty2 = coercionKind co2} in
not (from_ty `eqType` to_ty2),
vcat ([ text "expr:" <+> ppr expr
, text "co2:" <+> ppr co2
, text "co:" <+> ppr co ]) )
CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
expr (Coercion -> Coercion -> Coercion
mkTransCo Coercion
co2 Coercion
co)
mkCast (Tick t :: Tickish Id
t expr :: CoreExpr
expr) co :: Coercion
co
= Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t (CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
expr Coercion
co)
mkCast expr :: CoreExpr
expr co :: Coercion
co
= let Pair from_ty :: Type
from_ty _to_ty :: Type
_to_ty = Coercion -> Pair Type
coercionKind Coercion
co in
WARN( not (from_ty `eqType` exprType expr),
text "Trying to coerce" <+> text "(" <> ppr expr
$$ text "::" <+> ppr (exprType expr) <> text ")"
$$ ppr co $$ ppr (coercionType co) )
(CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
expr Coercion
co)
mkTick :: Tickish Id -> CoreExpr -> CoreExpr
mkTick :: Tickish Id -> CoreExpr -> CoreExpr
mkTick t :: Tickish Id
t orig_expr :: CoreExpr
orig_expr = (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' CoreExpr -> CoreExpr
forall a. a -> a
id CoreExpr -> CoreExpr
forall a. a -> a
id CoreExpr
orig_expr
where
canSplit :: Bool
canSplit = Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCanSplit Tickish Id
t Bool -> Bool -> Bool
&& Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoCount Tickish Id
t) TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
/= Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t
mkTick' :: (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr)
-> CoreExpr
-> CoreExpr
mkTick' :: (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' top :: CoreExpr -> CoreExpr
top rest :: CoreExpr -> CoreExpr
rest expr :: CoreExpr
expr = case CoreExpr
expr of
Tick t2 :: Tickish Id
t2 e :: CoreExpr
e
| ProfNote{} <- Tickish Id
t2, ProfNote{} <- Tickish Id
t -> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest CoreExpr
expr
| Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t2 TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
/= Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t -> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' (CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t2) CoreExpr -> CoreExpr
rest CoreExpr
e
| Tickish Id -> Tickish Id -> Bool
forall b. Eq b => Tickish b -> Tickish b -> Bool
tickishContains Tickish Id
t Tickish Id
t2 -> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' CoreExpr -> CoreExpr
top CoreExpr -> CoreExpr
rest CoreExpr
e
| Tickish Id -> Tickish Id -> Bool
forall b. Eq b => Tickish b -> Tickish b -> Bool
tickishContains Tickish Id
t2 Tickish Id
t -> CoreExpr
orig_expr
| Bool
otherwise -> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr
rest (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t2) CoreExpr
e
Cast e :: CoreExpr
e co :: Coercion
co -> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' (CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoreExpr -> Coercion -> CoreExpr)
-> Coercion -> CoreExpr -> CoreExpr
forall a b c. (a -> b -> c) -> b -> a -> c
flip CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast Coercion
co) CoreExpr -> CoreExpr
rest CoreExpr
e
Coercion co :: Coercion
co -> Coercion -> CoreExpr
forall b. Coercion -> Expr b
Coercion Coercion
co
Lam x :: Id
x e :: CoreExpr
e
| Bool -> Bool
not (Id -> Bool
isRuntimeVar Id
x) Bool -> Bool -> Bool
|| Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
/= TickishPlacement
PlaceRuntime
-> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' (CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
x) CoreExpr -> CoreExpr
rest CoreExpr
e
| Bool
canSplit
-> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoScope Tickish Id
t) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
x (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
mkTick (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoCount Tickish Id
t) CoreExpr
e
App f :: CoreExpr
f arg :: CoreExpr
arg
| Bool -> Bool
not (CoreExpr -> Bool
isRuntimeArg CoreExpr
arg)
-> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' (CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoreExpr -> CoreExpr -> CoreExpr)
-> CoreExpr -> CoreExpr -> CoreExpr
forall a b c. (a -> b -> c) -> b -> a -> c
flip CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
arg) CoreExpr -> CoreExpr
rest CoreExpr
f
| CoreExpr -> Bool
isSaturatedConApp CoreExpr
expr Bool -> Bool -> Bool
&& (Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
tTickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
==TickishPlacement
PlaceCostCentre Bool -> Bool -> Bool
|| Bool
canSplit)
-> if Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceCostCentre
then CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
tickHNFArgs Tickish Id
t CoreExpr
expr
else CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoScope Tickish Id
t) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
tickHNFArgs (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoCount Tickish Id
t) CoreExpr
expr
Var x :: Id
x
| Bool
notFunction Bool -> Bool -> Bool
&& Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceCostCentre
-> CoreExpr
orig_expr
| Bool
notFunction Bool -> Bool -> Bool
&& Bool
canSplit
-> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoScope Tickish Id
t) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest CoreExpr
expr
where
notFunction :: Bool
notFunction = Bool -> Bool
not (Type -> Bool
isFunTy (Id -> Type
idType Id
x))
Lit{}
| Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceCostCentre
-> CoreExpr
orig_expr
_any :: CoreExpr
_any -> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest CoreExpr
expr
mkTicks :: [Tickish Id] -> CoreExpr -> CoreExpr
mkTicks :: [Tickish Id] -> CoreExpr -> CoreExpr
mkTicks ticks :: [Tickish Id]
ticks expr :: CoreExpr
expr = (Tickish Id -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Id] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Id -> CoreExpr -> CoreExpr
mkTick CoreExpr
expr [Tickish Id]
ticks
isSaturatedConApp :: CoreExpr -> Bool
isSaturatedConApp :: CoreExpr -> Bool
isSaturatedConApp e :: CoreExpr
e = CoreExpr -> [CoreExpr] -> Bool
forall b. Expr b -> [Expr b] -> Bool
go CoreExpr
e []
where go :: Expr b -> [Expr b] -> Bool
go (App f :: Expr b
f a :: Expr b
a) as :: [Expr b]
as = Expr b -> [Expr b] -> Bool
go Expr b
f (Expr b
aExpr b -> [Expr b] -> [Expr b]
forall a. a -> [a] -> [a]
:[Expr b]
as)
go (Var fun :: Id
fun) args :: [Expr b]
args
= Id -> Bool
isConLikeId Id
fun Bool -> Bool -> Bool
&& Id -> Int
idArity Id
fun Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Expr b] -> Int
forall b. [Arg b] -> Int
valArgCount [Expr b]
args
go (Cast f :: Expr b
f _) as :: [Expr b]
as = Expr b -> [Expr b] -> Bool
go Expr b
f [Expr b]
as
go _ _ = Bool
False
mkTickNoHNF :: Tickish Id -> CoreExpr -> CoreExpr
mkTickNoHNF :: Tickish Id -> CoreExpr -> CoreExpr
mkTickNoHNF t :: Tickish Id
t e :: CoreExpr
e
| CoreExpr -> Bool
exprIsHNF CoreExpr
e = Tickish Id -> CoreExpr -> CoreExpr
tickHNFArgs Tickish Id
t CoreExpr
e
| Bool
otherwise = Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t CoreExpr
e
tickHNFArgs :: Tickish Id -> CoreExpr -> CoreExpr
tickHNFArgs :: Tickish Id -> CoreExpr -> CoreExpr
tickHNFArgs t :: Tickish Id
t e :: CoreExpr
e = Tickish Id -> CoreExpr -> CoreExpr
push Tickish Id
t CoreExpr
e
where
push :: Tickish Id -> CoreExpr -> CoreExpr
push t :: Tickish Id
t (App f :: CoreExpr
f (Type u :: Type
u)) = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (Tickish Id -> CoreExpr -> CoreExpr
push Tickish Id
t CoreExpr
f) (Type -> CoreExpr
forall b. Type -> Expr b
Type Type
u)
push t :: Tickish Id
t (App f :: CoreExpr
f arg :: CoreExpr
arg) = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (Tickish Id -> CoreExpr -> CoreExpr
push Tickish Id
t CoreExpr
f) (Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t CoreExpr
arg)
push _t :: Tickish Id
_t e :: CoreExpr
e = CoreExpr
e
stripTicksTop :: (Tickish Id -> Bool) -> Expr b -> ([Tickish Id], Expr b)
stripTicksTop :: (Tickish Id -> Bool) -> Expr b -> ([Tickish Id], Expr b)
stripTicksTop p :: Tickish Id -> Bool
p = [Tickish Id] -> Expr b -> ([Tickish Id], Expr b)
forall b. [Tickish Id] -> Expr b -> ([Tickish Id], Expr b)
go []
where go :: [Tickish Id] -> Expr b -> ([Tickish Id], Expr b)
go ts :: [Tickish Id]
ts (Tick t :: Tickish Id
t e :: Expr b
e) | Tickish Id -> Bool
p Tickish Id
t = [Tickish Id] -> Expr b -> ([Tickish Id], Expr b)
go (Tickish Id
tTickish Id -> [Tickish Id] -> [Tickish Id]
forall a. a -> [a] -> [a]
:[Tickish Id]
ts) Expr b
e
go ts :: [Tickish Id]
ts other :: Expr b
other = ([Tickish Id] -> [Tickish Id]
forall a. [a] -> [a]
reverse [Tickish Id]
ts, Expr b
other)
stripTicksTopE :: (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksTopE :: (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksTopE p :: Tickish Id -> Bool
p = Expr b -> Expr b
forall b. Expr b -> Expr b
go
where go :: Expr b -> Expr b
go (Tick t :: Tickish Id
t e :: Expr b
e) | Tickish Id -> Bool
p Tickish Id
t = Expr b -> Expr b
go Expr b
e
go other :: Expr b
other = Expr b
other
stripTicksTopT :: (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksTopT :: (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksTopT p :: Tickish Id -> Bool
p = [Tickish Id] -> Expr b -> [Tickish Id]
forall b. [Tickish Id] -> Expr b -> [Tickish Id]
go []
where go :: [Tickish Id] -> Expr b -> [Tickish Id]
go ts :: [Tickish Id]
ts (Tick t :: Tickish Id
t e :: Expr b
e) | Tickish Id -> Bool
p Tickish Id
t = [Tickish Id] -> Expr b -> [Tickish Id]
go (Tickish Id
tTickish Id -> [Tickish Id] -> [Tickish Id]
forall a. a -> [a] -> [a]
:[Tickish Id]
ts) Expr b
e
go ts :: [Tickish Id]
ts _ = [Tickish Id]
ts
stripTicksE :: (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksE :: (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksE p :: Tickish Id -> Bool
p expr :: Expr b
expr = Expr b -> Expr b
forall b. Expr b -> Expr b
go Expr b
expr
where go :: Expr b -> Expr b
go (App e :: Expr b
e a :: Expr b
a) = Expr b -> Expr b -> Expr b
forall b. Expr b -> Expr b -> Expr b
App (Expr b -> Expr b
go Expr b
e) (Expr b -> Expr b
go Expr b
a)
go (Lam b :: b
b e :: Expr b
e) = b -> Expr b -> Expr b
forall b. b -> Expr b -> Expr b
Lam b
b (Expr b -> Expr b
go Expr b
e)
go (Let b :: Bind b
b e :: Expr b
e) = Bind b -> Expr b -> Expr b
forall b. Bind b -> Expr b -> Expr b
Let (Bind b -> Bind b
go_bs Bind b
b) (Expr b -> Expr b
go Expr b
e)
go (Case e :: Expr b
e b :: b
b t :: Type
t as :: [Alt b]
as) = Expr b -> b -> Type -> [Alt b] -> Expr b
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case (Expr b -> Expr b
go Expr b
e) b
b Type
t ((Alt b -> Alt b) -> [Alt b] -> [Alt b]
forall a b. (a -> b) -> [a] -> [b]
map Alt b -> Alt b
go_a [Alt b]
as)
go (Cast e :: Expr b
e c :: Coercion
c) = Expr b -> Coercion -> Expr b
forall b. Expr b -> Coercion -> Expr b
Cast (Expr b -> Expr b
go Expr b
e) Coercion
c
go (Tick t :: Tickish Id
t e :: Expr b
e)
| Tickish Id -> Bool
p Tickish Id
t = Expr b -> Expr b
go Expr b
e
| Bool
otherwise = Tickish Id -> Expr b -> Expr b
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t (Expr b -> Expr b
go Expr b
e)
go other :: Expr b
other = Expr b
other
go_bs :: Bind b -> Bind b
go_bs (NonRec b :: b
b e :: Expr b
e) = b -> Expr b -> Bind b
forall b. b -> Expr b -> Bind b
NonRec b
b (Expr b -> Expr b
go Expr b
e)
go_bs (Rec bs :: [(b, Expr b)]
bs) = [(b, Expr b)] -> Bind b
forall b. [(b, Expr b)] -> Bind b
Rec (((b, Expr b) -> (b, Expr b)) -> [(b, Expr b)] -> [(b, Expr b)]
forall a b. (a -> b) -> [a] -> [b]
map (b, Expr b) -> (b, Expr b)
go_b [(b, Expr b)]
bs)
go_b :: (b, Expr b) -> (b, Expr b)
go_b (b :: b
b, e :: Expr b
e) = (b
b, Expr b -> Expr b
go Expr b
e)
go_a :: Alt b -> Alt b
go_a (c :: AltCon
c,bs :: [b]
bs,e :: Expr b
e) = (AltCon
c,[b]
bs, Expr b -> Expr b
go Expr b
e)
stripTicksT :: (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksT :: (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksT p :: Tickish Id -> Bool
p expr :: Expr b
expr = OrdList (Tickish Id) -> [Tickish Id]
forall a. OrdList a -> [a]
fromOL (OrdList (Tickish Id) -> [Tickish Id])
-> OrdList (Tickish Id) -> [Tickish Id]
forall a b. (a -> b) -> a -> b
$ Expr b -> OrdList (Tickish Id)
forall b. Expr b -> OrdList (Tickish Id)
go Expr b
expr
where go :: Expr b -> OrdList (Tickish Id)
go (App e :: Expr b
e a :: Expr b
a) = Expr b -> OrdList (Tickish Id)
go Expr b
e OrdList (Tickish Id)
-> OrdList (Tickish Id) -> OrdList (Tickish Id)
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` Expr b -> OrdList (Tickish Id)
go Expr b
a
go (Lam _ e :: Expr b
e) = Expr b -> OrdList (Tickish Id)
go Expr b
e
go (Let b :: Bind b
b e :: Expr b
e) = Bind b -> OrdList (Tickish Id)
go_bs Bind b
b OrdList (Tickish Id)
-> OrdList (Tickish Id) -> OrdList (Tickish Id)
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` Expr b -> OrdList (Tickish Id)
go Expr b
e
go (Case e :: Expr b
e _ _ as :: [Alt b]
as) = Expr b -> OrdList (Tickish Id)
go Expr b
e OrdList (Tickish Id)
-> OrdList (Tickish Id) -> OrdList (Tickish Id)
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` [OrdList (Tickish Id)] -> OrdList (Tickish Id)
forall a. [OrdList a] -> OrdList a
concatOL ((Alt b -> OrdList (Tickish Id))
-> [Alt b] -> [OrdList (Tickish Id)]
forall a b. (a -> b) -> [a] -> [b]
map Alt b -> OrdList (Tickish Id)
go_a [Alt b]
as)
go (Cast e :: Expr b
e _) = Expr b -> OrdList (Tickish Id)
go Expr b
e
go (Tick t :: Tickish Id
t e :: Expr b
e)
| Tickish Id -> Bool
p Tickish Id
t = Tickish Id
t Tickish Id -> OrdList (Tickish Id) -> OrdList (Tickish Id)
forall a. a -> OrdList a -> OrdList a
`consOL` Expr b -> OrdList (Tickish Id)
go Expr b
e
| Bool
otherwise = Expr b -> OrdList (Tickish Id)
go Expr b
e
go _ = OrdList (Tickish Id)
forall a. OrdList a
nilOL
go_bs :: Bind b -> OrdList (Tickish Id)
go_bs (NonRec _ e :: Expr b
e) = Expr b -> OrdList (Tickish Id)
go Expr b
e
go_bs (Rec bs :: [(b, Expr b)]
bs) = [OrdList (Tickish Id)] -> OrdList (Tickish Id)
forall a. [OrdList a] -> OrdList a
concatOL (((b, Expr b) -> OrdList (Tickish Id))
-> [(b, Expr b)] -> [OrdList (Tickish Id)]
forall a b. (a -> b) -> [a] -> [b]
map (b, Expr b) -> OrdList (Tickish Id)
go_b [(b, Expr b)]
bs)
go_b :: (b, Expr b) -> OrdList (Tickish Id)
go_b (_, e :: Expr b
e) = Expr b -> OrdList (Tickish Id)
go Expr b
e
go_a :: Alt b -> OrdList (Tickish Id)
go_a (_, _, e :: Expr b
e) = Expr b -> OrdList (Tickish Id)
go Expr b
e
bindNonRec :: Id -> CoreExpr -> CoreExpr -> CoreExpr
bindNonRec :: Id -> CoreExpr -> CoreExpr -> CoreExpr
bindNonRec bndr :: Id
bndr rhs :: CoreExpr
rhs body :: CoreExpr
body
| Id -> Bool
isTyVar Id
bndr = CoreExpr
let_bind
| Id -> Bool
isCoVar Id
bndr = if CoreExpr -> Bool
forall b. Expr b -> Bool
isCoArg CoreExpr
rhs then CoreExpr
let_bind
else CoreExpr
case_bind
| Id -> Bool
isJoinId Id
bndr = CoreExpr
let_bind
| Type -> CoreExpr -> Bool
needsCaseBinding (Id -> Type
idType Id
bndr) CoreExpr
rhs = CoreExpr
case_bind
| Bool
otherwise = CoreExpr
let_bind
where
case_bind :: CoreExpr
case_bind = CoreExpr -> Id -> Type -> [CoreAlt] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case CoreExpr
rhs Id
bndr (CoreExpr -> Type
exprType CoreExpr
body) [(AltCon
DEFAULT, [], CoreExpr
body)]
let_bind :: CoreExpr
let_bind = Bind Id -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (Id -> CoreExpr -> Bind Id
forall b. b -> Expr b -> Bind b
NonRec Id
bndr CoreExpr
rhs) CoreExpr
body
needsCaseBinding :: Type -> CoreExpr -> Bool
needsCaseBinding :: Type -> CoreExpr -> Bool
needsCaseBinding ty :: Type
ty rhs :: CoreExpr
rhs = HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty Bool -> Bool -> Bool
&& Bool -> Bool
not (CoreExpr -> Bool
exprOkForSpeculation CoreExpr
rhs)
mkAltExpr :: AltCon
-> [CoreBndr]
-> [Type]
-> CoreExpr
mkAltExpr :: AltCon -> [Id] -> [Type] -> CoreExpr
mkAltExpr (DataAlt con :: DataCon
con) args :: [Id]
args inst_tys :: [Type]
inst_tys
= DataCon -> [CoreExpr] -> CoreExpr
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
con ((Type -> CoreExpr) -> [Type] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Type -> CoreExpr
forall b. Type -> Expr b
Type [Type]
inst_tys [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Id] -> [CoreExpr]
forall b. [Id] -> [Expr b]
varsToCoreExprs [Id]
args)
mkAltExpr (LitAlt lit :: Literal
lit) [] []
= Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit
mkAltExpr (LitAlt _) _ _ = String -> CoreExpr
forall a. String -> a
panic "mkAltExpr LitAlt"
mkAltExpr DEFAULT _ _ = String -> CoreExpr
forall a. String -> a
panic "mkAltExpr DEFAULT"
findDefault :: [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault :: [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault ((DEFAULT,args :: [a]
args,rhs :: b
rhs) : alts :: [(AltCon, [a], b)]
alts) = ASSERT( null args ) (alts, Just rhs)
findDefault alts :: [(AltCon, [a], b)]
alts = ([(AltCon, [a], b)]
alts, Maybe b
forall a. Maybe a
Nothing)
addDefault :: [(AltCon, [a], b)] -> Maybe b -> [(AltCon, [a], b)]
addDefault :: [(AltCon, [a], b)] -> Maybe b -> [(AltCon, [a], b)]
addDefault alts :: [(AltCon, [a], b)]
alts Nothing = [(AltCon, [a], b)]
alts
addDefault alts :: [(AltCon, [a], b)]
alts (Just rhs :: b
rhs) = (AltCon
DEFAULT, [], b
rhs) (AltCon, [a], b) -> [(AltCon, [a], b)] -> [(AltCon, [a], b)]
forall a. a -> [a] -> [a]
: [(AltCon, [a], b)]
alts
isDefaultAlt :: (AltCon, a, b) -> Bool
isDefaultAlt :: (AltCon, a, b) -> Bool
isDefaultAlt (DEFAULT, _, _) = Bool
True
isDefaultAlt _ = Bool
False
findAlt :: AltCon -> [(AltCon, a, b)] -> Maybe (AltCon, a, b)
findAlt :: AltCon -> [(AltCon, a, b)] -> Maybe (AltCon, a, b)
findAlt con :: AltCon
con alts :: [(AltCon, a, b)]
alts
= case [(AltCon, a, b)]
alts of
(deflt :: (AltCon, a, b)
deflt@(DEFAULT,_,_):alts :: [(AltCon, a, b)]
alts) -> [(AltCon, a, b)] -> Maybe (AltCon, a, b) -> Maybe (AltCon, a, b)
forall b c.
[(AltCon, b, c)] -> Maybe (AltCon, b, c) -> Maybe (AltCon, b, c)
go [(AltCon, a, b)]
alts ((AltCon, a, b) -> Maybe (AltCon, a, b)
forall a. a -> Maybe a
Just (AltCon, a, b)
deflt)
_ -> [(AltCon, a, b)] -> Maybe (AltCon, a, b) -> Maybe (AltCon, a, b)
forall b c.
[(AltCon, b, c)] -> Maybe (AltCon, b, c) -> Maybe (AltCon, b, c)
go [(AltCon, a, b)]
alts Maybe (AltCon, a, b)
forall a. Maybe a
Nothing
where
go :: [(AltCon, b, c)] -> Maybe (AltCon, b, c) -> Maybe (AltCon, b, c)
go [] deflt :: Maybe (AltCon, b, c)
deflt = Maybe (AltCon, b, c)
deflt
go (alt :: (AltCon, b, c)
alt@(con1 :: AltCon
con1,_,_) : alts :: [(AltCon, b, c)]
alts) deflt :: Maybe (AltCon, b, c)
deflt
= case AltCon
con AltCon -> AltCon -> Ordering
`cmpAltCon` AltCon
con1 of
LT -> Maybe (AltCon, b, c)
deflt
EQ -> (AltCon, b, c) -> Maybe (AltCon, b, c)
forall a. a -> Maybe a
Just (AltCon, b, c)
alt
GT -> ASSERT( not (con1 == DEFAULT) ) go alts deflt
mergeAlts :: [(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts :: [(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts [] as2 :: [(AltCon, a, b)]
as2 = [(AltCon, a, b)]
as2
mergeAlts as1 :: [(AltCon, a, b)]
as1 [] = [(AltCon, a, b)]
as1
mergeAlts (a1 :: (AltCon, a, b)
a1:as1 :: [(AltCon, a, b)]
as1) (a2 :: (AltCon, a, b)
a2:as2 :: [(AltCon, a, b)]
as2)
= case (AltCon, a, b)
a1 (AltCon, a, b) -> (AltCon, a, b) -> Ordering
forall a b. (AltCon, a, b) -> (AltCon, a, b) -> Ordering
`cmpAlt` (AltCon, a, b)
a2 of
LT -> (AltCon, a, b)
a1 (AltCon, a, b) -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a. a -> [a] -> [a]
: [(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a b.
[(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts [(AltCon, a, b)]
as1 ((AltCon, a, b)
a2(AltCon, a, b) -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a. a -> [a] -> [a]
:[(AltCon, a, b)]
as2)
EQ -> (AltCon, a, b)
a1 (AltCon, a, b) -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a. a -> [a] -> [a]
: [(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a b.
[(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts [(AltCon, a, b)]
as1 [(AltCon, a, b)]
as2
GT -> (AltCon, a, b)
a2 (AltCon, a, b) -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a. a -> [a] -> [a]
: [(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a b.
[(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts ((AltCon, a, b)
a1(AltCon, a, b) -> [(AltCon, a, b)] -> [(AltCon, a, b)]
forall a. a -> [a] -> [a]
:[(AltCon, a, b)]
as1) [(AltCon, a, b)]
as2
trimConArgs :: AltCon -> [CoreArg] -> [CoreArg]
trimConArgs :: AltCon -> [CoreExpr] -> [CoreExpr]
trimConArgs DEFAULT args :: [CoreExpr]
args = ASSERT( null args ) []
trimConArgs (LitAlt _) args :: [CoreExpr]
args = ASSERT( null args ) []
trimConArgs (DataAlt dc :: DataCon
dc) args :: [CoreExpr]
args = [Id] -> [CoreExpr] -> [CoreExpr]
forall b a. [b] -> [a] -> [a]
dropList (DataCon -> [Id]
dataConUnivTyVars DataCon
dc) [CoreExpr]
args
filterAlts :: TyCon
-> [Type]
-> [AltCon]
-> [(AltCon, [Var], a)]
-> ([AltCon], [(AltCon, [Var], a)])
filterAlts :: TyCon
-> [Type]
-> [AltCon]
-> [(AltCon, [Id], a)]
-> ([AltCon], [(AltCon, [Id], a)])
filterAlts _tycon :: TyCon
_tycon inst_tys :: [Type]
inst_tys imposs_cons :: [AltCon]
imposs_cons alts :: [(AltCon, [Id], a)]
alts
= ([AltCon]
imposs_deflt_cons, [(AltCon, [Id], a)] -> Maybe a -> [(AltCon, [Id], a)]
forall a b. [(AltCon, [a], b)] -> Maybe b -> [(AltCon, [a], b)]
addDefault [(AltCon, [Id], a)]
trimmed_alts Maybe a
maybe_deflt)
where
(alts_wo_default :: [(AltCon, [Id], a)]
alts_wo_default, maybe_deflt :: Maybe a
maybe_deflt) = [(AltCon, [Id], a)] -> ([(AltCon, [Id], a)], Maybe a)
forall a b. [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault [(AltCon, [Id], a)]
alts
alt_cons :: [AltCon]
alt_cons = [AltCon
con | (con :: AltCon
con,_,_) <- [(AltCon, [Id], a)]
alts_wo_default]
trimmed_alts :: [(AltCon, [Id], a)]
trimmed_alts = ((AltCon, [Id], a) -> Bool)
-> [(AltCon, [Id], a)] -> [(AltCon, [Id], a)]
forall a. (a -> Bool) -> [a] -> [a]
filterOut ([Type] -> (AltCon, [Id], a) -> Bool
forall a b. [Type] -> (AltCon, a, b) -> Bool
impossible_alt [Type]
inst_tys) [(AltCon, [Id], a)]
alts_wo_default
imposs_cons_set :: Set AltCon
imposs_cons_set = [AltCon] -> Set AltCon
forall a. Ord a => [a] -> Set a
Set.fromList [AltCon]
imposs_cons
imposs_deflt_cons :: [AltCon]
imposs_deflt_cons =
[AltCon]
imposs_cons [AltCon] -> [AltCon] -> [AltCon]
forall a. [a] -> [a] -> [a]
++ (AltCon -> Bool) -> [AltCon] -> [AltCon]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (AltCon -> Set AltCon -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set AltCon
imposs_cons_set) [AltCon]
alt_cons
impossible_alt :: [Type] -> (AltCon, a, b) -> Bool
impossible_alt :: [Type] -> (AltCon, a, b) -> Bool
impossible_alt _ (con :: AltCon
con, _, _) | AltCon
con AltCon -> Set AltCon -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set AltCon
imposs_cons_set = Bool
True
impossible_alt inst_tys :: [Type]
inst_tys (DataAlt con :: DataCon
con, _, _) = [Type] -> DataCon -> Bool
dataConCannotMatch [Type]
inst_tys DataCon
con
impossible_alt _ _ = Bool
False
refineDefaultAlt :: [Unique]
-> TyCon
-> [Type]
-> [AltCon]
-> [CoreAlt]
-> (Bool, [CoreAlt])
refineDefaultAlt :: [Unique]
-> TyCon -> [Type] -> [AltCon] -> [CoreAlt] -> (Bool, [CoreAlt])
refineDefaultAlt us :: [Unique]
us tycon :: TyCon
tycon tys :: [Type]
tys imposs_deflt_cons :: [AltCon]
imposs_deflt_cons all_alts :: [CoreAlt]
all_alts
| (DEFAULT,_,rhs :: CoreExpr
rhs) : rest_alts :: [CoreAlt]
rest_alts <- [CoreAlt]
all_alts
, TyCon -> Bool
isAlgTyCon TyCon
tycon
, Bool -> Bool
not (TyCon -> Bool
isNewTyCon TyCon
tycon)
, Just all_cons :: [DataCon]
all_cons <- TyCon -> Maybe [DataCon]
tyConDataCons_maybe TyCon
tycon
, let imposs_data_cons :: UniqSet DataCon
imposs_data_cons = [DataCon] -> UniqSet DataCon
forall a. Uniquable a => [a] -> UniqSet a
mkUniqSet [DataCon
con | DataAlt con :: DataCon
con <- [AltCon]
imposs_deflt_cons]
impossible :: DataCon -> Bool
impossible con :: DataCon
con = DataCon
con DataCon -> UniqSet DataCon -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
`elementOfUniqSet` UniqSet DataCon
imposs_data_cons
Bool -> Bool -> Bool
|| [Type] -> DataCon -> Bool
dataConCannotMatch [Type]
tys DataCon
con
= case (DataCon -> Bool) -> [DataCon] -> [DataCon]
forall a. (a -> Bool) -> [a] -> [a]
filterOut DataCon -> Bool
impossible [DataCon]
all_cons of
[] -> (Bool
False, [CoreAlt]
rest_alts)
[con :: DataCon
con] -> (Bool
True, [CoreAlt] -> [CoreAlt] -> [CoreAlt]
forall a b.
[(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts [CoreAlt]
rest_alts [(DataCon -> AltCon
DataAlt DataCon
con, [Id]
ex_tvs [Id] -> [Id] -> [Id]
forall a. [a] -> [a] -> [a]
++ [Id]
arg_ids, CoreExpr
rhs)])
where
(ex_tvs :: [Id]
ex_tvs, arg_ids :: [Id]
arg_ids) = [Unique] -> DataCon -> [Type] -> ([Id], [Id])
dataConRepInstPat [Unique]
us DataCon
con [Type]
tys
_ -> (Bool
False, [CoreAlt]
all_alts)
| Bool
debugIsOn, TyCon -> Bool
isAlgTyCon TyCon
tycon, [DataCon] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (TyCon -> [DataCon]
tyConDataCons TyCon
tycon)
, Bool -> Bool
not (TyCon -> Bool
isFamilyTyCon TyCon
tycon Bool -> Bool -> Bool
|| TyCon -> Bool
isAbstractTyCon TyCon
tycon)
= (Bool
False, [CoreAlt]
all_alts)
| Bool
otherwise
= (Bool
False, [CoreAlt]
all_alts)
combineIdenticalAlts :: [AltCon]
-> [CoreAlt]
-> (Bool,
[AltCon],
[CoreAlt])
combineIdenticalAlts :: [AltCon] -> [CoreAlt] -> (Bool, [AltCon], [CoreAlt])
combineIdenticalAlts imposs_deflt_cons :: [AltCon]
imposs_deflt_cons ((con1 :: AltCon
con1,bndrs1 :: [Id]
bndrs1,rhs1 :: CoreExpr
rhs1) : rest_alts :: [CoreAlt]
rest_alts)
| (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
isDeadBinder [Id]
bndrs1
, Bool -> Bool
not ([CoreAlt] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreAlt]
elim_rest)
= (Bool
True, [AltCon]
imposs_deflt_cons', CoreAlt
forall a. (AltCon, [a], CoreExpr)
deflt_alt CoreAlt -> [CoreAlt] -> [CoreAlt]
forall a. a -> [a] -> [a]
: [CoreAlt]
filtered_rest)
where
(elim_rest :: [CoreAlt]
elim_rest, filtered_rest :: [CoreAlt]
filtered_rest) = (CoreAlt -> Bool) -> [CoreAlt] -> ([CoreAlt], [CoreAlt])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition CoreAlt -> Bool
forall (t :: * -> *) a. Foldable t => (a, t Id, CoreExpr) -> Bool
identical_to_alt1 [CoreAlt]
rest_alts
deflt_alt :: (AltCon, [a], CoreExpr)
deflt_alt = (AltCon
DEFAULT, [], [Tickish Id] -> CoreExpr -> CoreExpr
mkTicks ([[Tickish Id]] -> [Tickish Id]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Tickish Id]]
tickss) CoreExpr
rhs1)
imposs_deflt_cons' :: [AltCon]
imposs_deflt_cons' = [AltCon]
imposs_deflt_cons [AltCon] -> [AltCon] -> [AltCon]
forall a. Ord a => [a] -> [a] -> [a]
`minusList` [AltCon]
elim_cons
elim_cons :: [AltCon]
elim_cons = [AltCon]
elim_con1 [AltCon] -> [AltCon] -> [AltCon]
forall a. [a] -> [a] -> [a]
++ (CoreAlt -> AltCon) -> [CoreAlt] -> [AltCon]
forall a b. (a -> b) -> [a] -> [b]
map CoreAlt -> AltCon
forall a b c. (a, b, c) -> a
fstOf3 [CoreAlt]
elim_rest
elim_con1 :: [AltCon]
elim_con1 = case AltCon
con1 of
DEFAULT -> []
_ -> [AltCon
con1]
cheapEqTicked :: Expr b -> Expr b -> Bool
cheapEqTicked e1 :: Expr b
e1 e2 :: Expr b
e2 = (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
forall b. (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable Expr b
e1 Expr b
e2
identical_to_alt1 :: (a, t Id, CoreExpr) -> Bool
identical_to_alt1 (_con :: a
_con,bndrs :: t Id
bndrs,rhs :: CoreExpr
rhs)
= (Id -> Bool) -> t Id -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
isDeadBinder t Id
bndrs Bool -> Bool -> Bool
&& CoreExpr
rhs CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqTicked` CoreExpr
rhs1
tickss :: [[Tickish Id]]
tickss = (CoreAlt -> [Tickish Id]) -> [CoreAlt] -> [[Tickish Id]]
forall a b. (a -> b) -> [a] -> [b]
map ((Tickish Id -> Bool) -> CoreExpr -> [Tickish Id]
forall b. (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksT Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable (CoreExpr -> [Tickish Id])
-> (CoreAlt -> CoreExpr) -> CoreAlt -> [Tickish Id]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreAlt -> CoreExpr
forall a b c. (a, b, c) -> c
thdOf3) [CoreAlt]
elim_rest
combineIdenticalAlts imposs_cons :: [AltCon]
imposs_cons alts :: [CoreAlt]
alts
= (Bool
False, [AltCon]
imposs_cons, [CoreAlt]
alts)
exprIsTrivial :: CoreExpr -> Bool
exprIsTrivial :: CoreExpr -> Bool
exprIsTrivial (Var _) = Bool
True
exprIsTrivial (Type _) = Bool
True
exprIsTrivial (Coercion _) = Bool
True
exprIsTrivial (Lit lit :: Literal
lit) = Literal -> Bool
litIsTrivial Literal
lit
exprIsTrivial (App e :: CoreExpr
e arg :: CoreExpr
arg) = Bool -> Bool
not (CoreExpr -> Bool
isRuntimeArg CoreExpr
arg) Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Lam b :: Id
b e :: CoreExpr
e) = Bool -> Bool
not (Id -> Bool
isRuntimeVar Id
b) Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Tick t :: Tickish Id
t e :: CoreExpr
e) = Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Id
t) Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Cast e :: CoreExpr
e _) = CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Case e :: CoreExpr
e _ _ []) = CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial _ = Bool
False
getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id
getIdFromTrivialExpr :: CoreExpr -> Id
getIdFromTrivialExpr e :: CoreExpr
e
= Id -> Maybe Id -> Id
forall a. a -> Maybe a -> a
fromMaybe (String -> SDoc -> Id
forall a. HasCallStack => String -> SDoc -> a
pprPanic "getIdFromTrivialExpr" (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e))
(CoreExpr -> Maybe Id
getIdFromTrivialExpr_maybe CoreExpr
e)
getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
getIdFromTrivialExpr_maybe e :: CoreExpr
e
= CoreExpr -> Maybe Id
go CoreExpr
e
where
go :: CoreExpr -> Maybe Id
go (App f :: CoreExpr
f t :: CoreExpr
t) | Bool -> Bool
not (CoreExpr -> Bool
isRuntimeArg CoreExpr
t) = CoreExpr -> Maybe Id
go CoreExpr
f
go (Tick t :: Tickish Id
t e :: CoreExpr
e) | Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Id
t) = CoreExpr -> Maybe Id
go CoreExpr
e
go (Cast e :: CoreExpr
e _) = CoreExpr -> Maybe Id
go CoreExpr
e
go (Lam b :: Id
b e :: CoreExpr
e) | Bool -> Bool
not (Id -> Bool
isRuntimeVar Id
b) = CoreExpr -> Maybe Id
go CoreExpr
e
go (Case e :: CoreExpr
e _ _ []) = CoreExpr -> Maybe Id
go CoreExpr
e
go (Var v :: Id
v) = Id -> Maybe Id
forall a. a -> Maybe a
Just Id
v
go _ = Maybe Id
forall a. Maybe a
Nothing
exprIsBottom :: CoreExpr -> Bool
exprIsBottom :: CoreExpr -> Bool
exprIsBottom e :: CoreExpr
e
| Type -> Bool
isEmptyTy (CoreExpr -> Type
exprType CoreExpr
e)
= Bool
True
| Bool
otherwise
= Int -> CoreExpr -> Bool
go 0 CoreExpr
e
where
go :: Int -> CoreExpr -> Bool
go n :: Int
n (Var v :: Id
v) = Id -> Bool
isBottomingId Id
v Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Id -> Int
idArity Id
v
go n :: Int
n (App e :: CoreExpr
e a :: CoreExpr
a) | CoreExpr -> Bool
forall b. Expr b -> Bool
isTypeArg CoreExpr
a = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) CoreExpr
e
go n :: Int
n (Tick _ e :: CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Cast e :: CoreExpr
e _) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Let _ e :: CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Lam v :: Id
v e :: CoreExpr
e) | Id -> Bool
isTyVar Id
v = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go _ (Case _ _ _ alts :: [CoreAlt]
alts) = [CoreAlt] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreAlt]
alts
go _ _ = Bool
False
exprIsDupable :: DynFlags -> CoreExpr -> Bool
exprIsDupable :: DynFlags -> CoreExpr -> Bool
exprIsDupable dflags :: DynFlags
dflags e :: CoreExpr
e
= Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (Int -> CoreExpr -> Maybe Int
go Int
dupAppSize CoreExpr
e)
where
go :: Int -> CoreExpr -> Maybe Int
go :: Int -> CoreExpr -> Maybe Int
go n :: Int
n (Type {}) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
go n :: Int
n (Coercion {}) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
go n :: Int
n (Var {}) = Int -> Maybe Int
decrement Int
n
go n :: Int
n (Tick _ e :: CoreExpr
e) = Int -> CoreExpr -> Maybe Int
go Int
n CoreExpr
e
go n :: Int
n (Cast e :: CoreExpr
e _) = Int -> CoreExpr -> Maybe Int
go Int
n CoreExpr
e
go n :: Int
n (App f :: CoreExpr
f a :: CoreExpr
a) | Just n' :: Int
n' <- Int -> CoreExpr -> Maybe Int
go Int
n CoreExpr
a = Int -> CoreExpr -> Maybe Int
go Int
n' CoreExpr
f
go n :: Int
n (Lit lit :: Literal
lit) | DynFlags -> Literal -> Bool
litIsDupable DynFlags
dflags Literal
lit = Int -> Maybe Int
decrement Int
n
go _ _ = Maybe Int
forall a. Maybe a
Nothing
decrement :: Int -> Maybe Int
decrement :: Int -> Maybe Int
decrement 0 = Maybe Int
forall a. Maybe a
Nothing
decrement n :: Int
n = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1)
dupAppSize :: Int
dupAppSize :: Int
dupAppSize = 8
exprIsWorkFree :: CoreExpr -> Bool
exprIsWorkFree :: CoreExpr -> Bool
exprIsWorkFree = CheapAppFun -> CoreExpr -> Bool
exprIsCheapX CheapAppFun
isWorkFreeApp
exprIsCheap :: CoreExpr -> Bool
exprIsCheap :: CoreExpr -> Bool
exprIsCheap = CheapAppFun -> CoreExpr -> Bool
exprIsCheapX CheapAppFun
isCheapApp
exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool
exprIsCheapX :: CheapAppFun -> CoreExpr -> Bool
exprIsCheapX ok_app :: CheapAppFun
ok_app e :: CoreExpr
e
= CoreExpr -> Bool
ok CoreExpr
e
where
ok :: CoreExpr -> Bool
ok e :: CoreExpr
e = Int -> CoreExpr -> Bool
go 0 CoreExpr
e
go :: Int -> CoreExpr -> Bool
go n :: Int
n (Var v :: Id
v) = CheapAppFun
ok_app Id
v Int
n
go _ (Lit {}) = Bool
True
go _ (Type {}) = Bool
True
go _ (Coercion {}) = Bool
True
go n :: Int
n (Cast e :: CoreExpr
e _) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Case scrut :: CoreExpr
scrut _ _ alts :: [CoreAlt]
alts) = CoreExpr -> Bool
ok CoreExpr
scrut Bool -> Bool -> Bool
&&
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Int -> CoreExpr -> Bool
go Int
n CoreExpr
rhs | (_,_,rhs :: CoreExpr
rhs) <- [CoreAlt]
alts ]
go n :: Int
n (Tick t :: Tickish Id
t e :: CoreExpr
e) | Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Id
t = Bool
False
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Lam x :: Id
x e :: CoreExpr
e) | Id -> Bool
isRuntimeVar Id
x = Int
nInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==0 Bool -> Bool -> Bool
|| Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (App f :: CoreExpr
f e :: CoreExpr
e) | CoreExpr -> Bool
isRuntimeArg CoreExpr
e = Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) CoreExpr
f Bool -> Bool -> Bool
&& CoreExpr -> Bool
ok CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
f
go n :: Int
n (Let (NonRec _ r :: CoreExpr
r) e :: CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e Bool -> Bool -> Bool
&& CoreExpr -> Bool
ok CoreExpr
r
go n :: Int
n (Let (Rec prs :: [(Id, CoreExpr)]
prs) e :: CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e Bool -> Bool -> Bool
&& ((Id, CoreExpr) -> Bool) -> [(Id, CoreExpr)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CoreExpr -> Bool
ok (CoreExpr -> Bool)
-> ((Id, CoreExpr) -> CoreExpr) -> (Id, CoreExpr) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Id, CoreExpr) -> CoreExpr
forall a b. (a, b) -> b
snd) [(Id, CoreExpr)]
prs
exprIsExpandable :: CoreExpr -> Bool
exprIsExpandable :: CoreExpr -> Bool
exprIsExpandable e :: CoreExpr
e
= CoreExpr -> Bool
ok CoreExpr
e
where
ok :: CoreExpr -> Bool
ok e :: CoreExpr
e = Int -> CoreExpr -> Bool
go 0 CoreExpr
e
go :: Int -> CoreExpr -> Bool
go n :: Int
n (Var v :: Id
v) = CheapAppFun
isExpandableApp Id
v Int
n
go _ (Lit {}) = Bool
True
go _ (Type {}) = Bool
True
go _ (Coercion {}) = Bool
True
go n :: Int
n (Cast e :: CoreExpr
e _) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Tick t :: Tickish Id
t e :: CoreExpr
e) | Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Id
t = Bool
False
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (Lam x :: Id
x e :: CoreExpr
e) | Id -> Bool
isRuntimeVar Id
x = Int
nInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==0 Bool -> Bool -> Bool
|| Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go n :: Int
n (App f :: CoreExpr
f e :: CoreExpr
e) | CoreExpr -> Bool
isRuntimeArg CoreExpr
e = Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) CoreExpr
f Bool -> Bool -> Bool
&& CoreExpr -> Bool
ok CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
f
go _ (Case {}) = Bool
False
go _ (Let {}) = Bool
False
type CheapAppFun = Id -> Arity -> Bool
isWorkFreeApp :: CheapAppFun
isWorkFreeApp :: CheapAppFun
isWorkFreeApp fn :: Id
fn n_val_args :: Int
n_val_args
| Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
= Bool
True
| Int
n_val_args Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Id -> Int
idArity Id
fn
= Bool
True
| Bool
otherwise
= case Id -> IdDetails
idDetails Id
fn of
DataConWorkId {} -> Bool
True
_ -> Bool
False
isCheapApp :: CheapAppFun
isCheapApp :: CheapAppFun
isCheapApp fn :: Id
fn n_val_args :: Int
n_val_args
| CheapAppFun
isWorkFreeApp Id
fn Int
n_val_args = Bool
True
| Id -> Bool
isBottomingId Id
fn = Bool
True
| Bool
otherwise
= case Id -> IdDetails
idDetails Id
fn of
DataConWorkId {} -> Bool
True
RecSelId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1
ClassOpId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1
PrimOpId op :: PrimOp
op -> PrimOp -> Bool
primOpIsCheap PrimOp
op
_ -> Bool
False
isExpandableApp :: CheapAppFun
isExpandableApp :: CheapAppFun
isExpandableApp fn :: Id
fn n_val_args :: Int
n_val_args
| CheapAppFun
isWorkFreeApp Id
fn Int
n_val_args = Bool
True
| Bool
otherwise
= case Id -> IdDetails
idDetails Id
fn of
DataConWorkId {} -> Bool
True
RecSelId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1
ClassOpId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1
PrimOpId {} -> Bool
False
_ | Id -> Bool
isBottomingId Id
fn -> Bool
False
| RuleMatchInfo -> Bool
isConLike (Id -> RuleMatchInfo
idRuleMatchInfo Id
fn) -> Bool
True
| Bool
all_args_are_preds -> Bool
True
| Bool
otherwise -> Bool
False
where
all_args_are_preds :: Bool
all_args_are_preds = Int -> Type -> Bool
forall a. (Eq a, Num a) => a -> Type -> Bool
all_pred_args Int
n_val_args (Id -> Type
idType Id
fn)
all_pred_args :: a -> Type -> Bool
all_pred_args n_val_args :: a
n_val_args ty :: Type
ty
| a
n_val_args a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== 0
= Bool
True
| Just (bndr :: TyCoBinder
bndr, ty :: Type
ty) <- Type -> Maybe (TyCoBinder, Type)
splitPiTy_maybe Type
ty
= TyCoBinder -> (TyCoVarBinder -> Bool) -> (Type -> Bool) -> Bool
forall a. TyCoBinder -> (TyCoVarBinder -> a) -> (Type -> a) -> a
caseBinder TyCoBinder
bndr
(\_tv :: TyCoVarBinder
_tv -> a -> Type -> Bool
all_pred_args a
n_val_args Type
ty)
(\bndr_ty :: Type
bndr_ty -> Type -> Bool
isPredTy Type
bndr_ty Bool -> Bool -> Bool
&& a -> Type -> Bool
all_pred_args (a
n_val_argsa -> a -> a
forall a. Num a => a -> a -> a
-1) Type
ty)
| Bool
otherwise
= Bool
False
exprOkForSpeculation, exprOkForSideEffects :: CoreExpr -> Bool
exprOkForSpeculation :: CoreExpr -> Bool
exprOkForSpeculation = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primOpOkForSpeculation
exprOkForSideEffects :: CoreExpr -> Bool
exprOkForSideEffects = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primOpOkForSideEffects
expr_ok :: (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok :: (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok _ (Lit _) = Bool
True
expr_ok _ (Type _) = Bool
True
expr_ok _ (Coercion _) = Bool
True
expr_ok primop_ok :: PrimOp -> Bool
primop_ok (Var v :: Id
v) = (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool
app_ok PrimOp -> Bool
primop_ok Id
v []
expr_ok primop_ok :: PrimOp -> Bool
primop_ok (Cast e :: CoreExpr
e _) = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
e
expr_ok primop_ok :: PrimOp -> Bool
primop_ok (Lam b :: Id
b e :: CoreExpr
e)
| Id -> Bool
isTyVar Id
b = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
e
| Bool
otherwise = Bool
True
expr_ok primop_ok :: PrimOp -> Bool
primop_ok (Tick tickish :: Tickish Id
tickish e :: CoreExpr
e)
| Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Id
tickish = Bool
False
| Bool
otherwise = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
e
expr_ok _ (Let {}) = Bool
False
expr_ok primop_ok :: PrimOp -> Bool
primop_ok (Case scrut :: CoreExpr
scrut bndr :: Id
bndr _ alts :: [CoreAlt]
alts)
=
(PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
scrut
Bool -> Bool -> Bool
&& HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Id -> Type
idType Id
bndr)
Bool -> Bool -> Bool
&& (CoreAlt -> Bool) -> [CoreAlt] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\(_,_,rhs :: CoreExpr
rhs) -> (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
rhs) [CoreAlt]
alts
Bool -> Bool -> Bool
&& [CoreAlt] -> Bool
forall b. [Alt b] -> Bool
altsAreExhaustive [CoreAlt]
alts
expr_ok primop_ok :: PrimOp -> Bool
primop_ok other_expr :: CoreExpr
other_expr
| (expr :: CoreExpr
expr, args :: [CoreExpr]
args) <- CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
other_expr
= case (Tickish Id -> Bool) -> CoreExpr -> CoreExpr
forall b. (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksTopE (Bool -> Bool
not (Bool -> Bool) -> (Tickish Id -> Bool) -> Tickish Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts) CoreExpr
expr of
Var f :: Id
f -> (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool
app_ok PrimOp -> Bool
primop_ok Id
f [CoreExpr]
args
Lit lit :: Literal
lit -> ASSERT( lit == rubbishLit ) True
_ -> Bool
False
app_ok :: (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool
app_ok :: (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool
app_ok primop_ok :: PrimOp -> Bool
primop_ok fun :: Id
fun args :: [CoreExpr]
args
= case Id -> IdDetails
idDetails Id
fun of
DFunId new_type :: Bool
new_type -> Bool -> Bool
not Bool
new_type
DataConWorkId {} -> Bool
True
PrimOpId op :: PrimOp
op
| PrimOp -> Bool
isDivOp PrimOp
op
, [arg1 :: CoreExpr
arg1, Lit lit :: Literal
lit] <- [CoreExpr]
args
-> Bool -> Bool
not (Literal -> Bool
isZeroLit Literal
lit) Bool -> Bool -> Bool
&& (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
arg1
| PrimOp
SeqOp <- PrimOp
op
-> Bool
False
| PrimOp
DataToTagOp <- PrimOp
op
-> Bool
False
| Bool
otherwise
-> PrimOp -> Bool
primop_ok PrimOp
op
Bool -> Bool -> Bool
&& [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ((TyCoBinder -> CoreExpr -> Bool)
-> [TyCoBinder] -> [CoreExpr] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith TyCoBinder -> CoreExpr -> Bool
primop_arg_ok [TyCoBinder]
arg_tys [CoreExpr]
args)
_other :: IdDetails
_other -> HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Id -> Type
idType Id
fun)
Bool -> Bool -> Bool
|| Id -> Int
idArity Id
fun Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n_val_args
where
n_val_args :: Int
n_val_args = [CoreExpr] -> Int
forall b. [Arg b] -> Int
valArgCount [CoreExpr]
args
where
(arg_tys :: [TyCoBinder]
arg_tys, _) = Type -> ([TyCoBinder], Type)
splitPiTys (Id -> Type
idType Id
fun)
primop_arg_ok :: TyBinder -> CoreExpr -> Bool
primop_arg_ok :: TyCoBinder -> CoreExpr -> Bool
primop_arg_ok (Named _) _ = Bool
True
primop_arg_ok (Anon ty :: Type
ty) arg :: CoreExpr
arg
| HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
arg
| Bool
otherwise = Bool
True
altsAreExhaustive :: [Alt b] -> Bool
altsAreExhaustive :: [Alt b] -> Bool
altsAreExhaustive []
= Bool
False
altsAreExhaustive ((con1 :: AltCon
con1,_,_) : alts :: [Alt b]
alts)
= case AltCon
con1 of
DEFAULT -> Bool
True
LitAlt {} -> Bool
False
DataAlt c :: DataCon
c -> [Alt b]
alts [Alt b] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthIs` (TyCon -> Int
tyConFamilySize (DataCon -> TyCon
dataConTyCon DataCon
c) Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)
isDivOp :: PrimOp -> Bool
isDivOp :: PrimOp -> Bool
isDivOp IntQuotOp = Bool
True
isDivOp IntRemOp = Bool
True
isDivOp WordQuotOp = Bool
True
isDivOp WordRemOp = Bool
True
isDivOp FloatDivOp = Bool
True
isDivOp DoubleDivOp = Bool
True
isDivOp _ = Bool
False
exprIsHNF :: CoreExpr -> Bool
exprIsHNF :: CoreExpr -> Bool
exprIsHNF = (Id -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike Id -> Bool
isDataConWorkId Unfolding -> Bool
isEvaldUnfolding
exprIsConLike :: CoreExpr -> Bool
exprIsConLike :: CoreExpr -> Bool
exprIsConLike = (Id -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike Id -> Bool
isConLikeId Unfolding -> Bool
isConLikeUnfolding
exprIsHNFlike :: (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike :: (Id -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike is_con :: Id -> Bool
is_con is_con_unf :: Unfolding -> Bool
is_con_unf = CoreExpr -> Bool
is_hnf_like
where
is_hnf_like :: CoreExpr -> Bool
is_hnf_like (Var v :: Id
v)
= CheapAppFun
id_app_is_value Id
v 0
Bool -> Bool -> Bool
|| Unfolding -> Bool
is_con_unf (Id -> Unfolding
idUnfolding Id
v)
is_hnf_like (Lit _) = Bool
True
is_hnf_like (Type _) = Bool
True
is_hnf_like (Coercion _) = Bool
True
is_hnf_like (Lam b :: Id
b e :: CoreExpr
e) = Id -> Bool
isRuntimeVar Id
b Bool -> Bool -> Bool
|| CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (Tick tickish :: Tickish Id
tickish e :: CoreExpr
e) = Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Id
tickish)
Bool -> Bool -> Bool
&& CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (Cast e :: CoreExpr
e _) = CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (App e :: CoreExpr
e a :: CoreExpr
a)
| CoreExpr -> Bool
forall b. Expr b -> Bool
isValArg CoreExpr
a = CoreExpr -> Int -> Bool
app_is_value CoreExpr
e 1
| Bool
otherwise = CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (Let _ e :: CoreExpr
e) = CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like _ = Bool
False
app_is_value :: CoreExpr -> Int -> Bool
app_is_value :: CoreExpr -> Int -> Bool
app_is_value (Var f :: Id
f) nva :: Int
nva = CheapAppFun
id_app_is_value Id
f Int
nva
app_is_value (Tick _ f :: CoreExpr
f) nva :: Int
nva = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f Int
nva
app_is_value (Cast f :: CoreExpr
f _) nva :: Int
nva = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f Int
nva
app_is_value (App f :: CoreExpr
f a :: CoreExpr
a) nva :: Int
nva
| CoreExpr -> Bool
forall b. Expr b -> Bool
isValArg CoreExpr
a = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f (Int
nva Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
| Bool
otherwise = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f Int
nva
app_is_value _ _ = Bool
False
id_app_is_value :: CheapAppFun
id_app_is_value id :: Id
id n_val_args :: Int
n_val_args
= Id -> Bool
is_con Id
id
Bool -> Bool -> Bool
|| Id -> Int
idArity Id
id Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n_val_args
Bool -> Bool -> Bool
|| Id
id Id -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
absentErrorIdKey
exprIsTopLevelBindable :: CoreExpr -> Type -> Bool
exprIsTopLevelBindable :: CoreExpr -> Type -> Bool
exprIsTopLevelBindable expr :: CoreExpr
expr ty :: Type
ty
= Bool -> Bool
not (HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
ty)
Bool -> Bool -> Bool
|| CoreExpr -> Bool
exprIsTickedString CoreExpr
expr
exprIsTickedString :: CoreExpr -> Bool
exprIsTickedString :: CoreExpr -> Bool
exprIsTickedString = Maybe ByteString -> Bool
forall a. Maybe a -> Bool
isJust (Maybe ByteString -> Bool)
-> (CoreExpr -> Maybe ByteString) -> CoreExpr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreExpr -> Maybe ByteString
exprIsTickedString_maybe
exprIsTickedString_maybe :: CoreExpr -> Maybe ByteString
exprIsTickedString_maybe :: CoreExpr -> Maybe ByteString
exprIsTickedString_maybe (Lit (LitString bs :: ByteString
bs)) = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
bs
exprIsTickedString_maybe (Tick t :: Tickish Id
t e :: CoreExpr
e)
| Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
t TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceCostCentre = Maybe ByteString
forall a. Maybe a
Nothing
| Bool
otherwise = CoreExpr -> Maybe ByteString
exprIsTickedString_maybe CoreExpr
e
exprIsTickedString_maybe _ = Maybe ByteString
forall a. Maybe a
Nothing
dataConRepInstPat :: [Unique] -> DataCon -> [Type] -> ([TyCoVar], [Id])
dataConRepFSInstPat :: [FastString] -> [Unique] -> DataCon -> [Type] -> ([TyCoVar], [Id])
dataConRepInstPat :: [Unique] -> DataCon -> [Type] -> ([Id], [Id])
dataConRepInstPat = [FastString] -> [Unique] -> DataCon -> [Type] -> ([Id], [Id])
dataConInstPat (FastString -> [FastString]
forall a. a -> [a]
repeat ((String -> FastString
fsLit "ipv")))
dataConRepFSInstPat :: [FastString] -> [Unique] -> DataCon -> [Type] -> ([Id], [Id])
dataConRepFSInstPat = [FastString] -> [Unique] -> DataCon -> [Type] -> ([Id], [Id])
dataConInstPat
dataConInstPat :: [FastString]
-> [Unique]
-> DataCon
-> [Type]
-> ([TyCoVar], [Id])
dataConInstPat :: [FastString] -> [Unique] -> DataCon -> [Type] -> ([Id], [Id])
dataConInstPat fss :: [FastString]
fss uniqs :: [Unique]
uniqs con :: DataCon
con inst_tys :: [Type]
inst_tys
= ASSERT( univ_tvs `equalLength` inst_tys )
([Id]
ex_bndrs, [Id]
arg_ids)
where
univ_tvs :: [Id]
univ_tvs = DataCon -> [Id]
dataConUnivTyVars DataCon
con
ex_tvs :: [Id]
ex_tvs = DataCon -> [Id]
dataConExTyCoVars DataCon
con
arg_tys :: [Type]
arg_tys = DataCon -> [Type]
dataConRepArgTys DataCon
con
arg_strs :: [StrictnessMark]
arg_strs = DataCon -> [StrictnessMark]
dataConRepStrictness DataCon
con
n_ex :: Int
n_ex = [Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
ex_tvs
(ex_uniqs :: [Unique]
ex_uniqs, id_uniqs :: [Unique]
id_uniqs) = Int -> [Unique] -> ([Unique], [Unique])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n_ex [Unique]
uniqs
(ex_fss :: [FastString]
ex_fss, id_fss :: [FastString]
id_fss) = Int -> [FastString] -> ([FastString], [FastString])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n_ex [FastString]
fss
univ_subst :: TCvSubst
univ_subst = [Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
univ_tvs [Type]
inst_tys
(full_subst :: TCvSubst
full_subst, ex_bndrs :: [Id]
ex_bndrs) = (TCvSubst -> (Id, FastString, Unique) -> (TCvSubst, Id))
-> TCvSubst -> [(Id, FastString, Unique)] -> (TCvSubst, [Id])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL TCvSubst -> (Id, FastString, Unique) -> (TCvSubst, Id)
mk_ex_var TCvSubst
univ_subst
([Id] -> [FastString] -> [Unique] -> [(Id, FastString, Unique)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Id]
ex_tvs [FastString]
ex_fss [Unique]
ex_uniqs)
mk_ex_var :: TCvSubst -> (TyCoVar, FastString, Unique) -> (TCvSubst, TyCoVar)
mk_ex_var :: TCvSubst -> (Id, FastString, Unique) -> (TCvSubst, Id)
mk_ex_var subst :: TCvSubst
subst (tv :: Id
tv, fs :: FastString
fs, uniq :: Unique
uniq) = (TCvSubst -> Id -> Id -> TCvSubst
Type.extendTCvSubstWithClone TCvSubst
subst Id
tv
Id
new_tv
, Id
new_tv)
where
new_tv :: Id
new_tv | Id -> Bool
isTyVar Id
tv
= Name -> Type -> Id
mkTyVar (Unique -> FastString -> Name
mkSysTvName Unique
uniq FastString
fs) Type
kind
| Bool
otherwise
= Name -> Type -> Id
mkCoVar (Unique -> FastString -> Name
mkSystemVarName Unique
uniq FastString
fs) Type
kind
kind :: Type
kind = TCvSubst -> Type -> Type
Type.substTyUnchecked TCvSubst
subst (Id -> Type
varType Id
tv)
arg_ids :: [Id]
arg_ids = (Unique -> FastString -> Type -> StrictnessMark -> Id)
-> [Unique] -> [FastString] -> [Type] -> [StrictnessMark] -> [Id]
forall a b c d e.
(a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
zipWith4 Unique -> FastString -> Type -> StrictnessMark -> Id
mk_id_var [Unique]
id_uniqs [FastString]
id_fss [Type]
arg_tys [StrictnessMark]
arg_strs
mk_id_var :: Unique -> FastString -> Type -> StrictnessMark -> Id
mk_id_var uniq :: Unique
uniq fs :: FastString
fs ty :: Type
ty str :: StrictnessMark
str
= StrictnessMark -> Id -> Id
setCaseBndrEvald StrictnessMark
str (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$
Name -> Type -> Id
mkLocalIdOrCoVar Name
name (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
Type.substTy TCvSubst
full_subst Type
ty)
where
name :: Name
name = Unique -> OccName -> SrcSpan -> Name
mkInternalName Unique
uniq (FastString -> OccName
mkVarOccFS FastString
fs) SrcSpan
noSrcSpan
cheapEqExpr :: Expr b -> Expr b -> Bool
cheapEqExpr :: Expr b -> Expr b -> Bool
cheapEqExpr = (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
forall b. (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' (Bool -> Tickish Id -> Bool
forall a b. a -> b -> a
const Bool
False)
cheapEqExpr' :: (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' :: (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' ignoreTick :: Tickish Id -> Bool
ignoreTick = Expr b -> Expr b -> Bool
forall b. Expr b -> Expr b -> Bool
go_s
where go_s :: Expr b -> Expr b -> Bool
go_s = Expr b -> Expr b -> Bool
go (Expr b -> Expr b -> Bool)
-> (Expr b -> Expr b) -> Expr b -> Expr b -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (Tickish Id -> Bool) -> Expr b -> Expr b
forall b. (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksTopE Tickish Id -> Bool
ignoreTick
go :: Expr b -> Expr b -> Bool
go (Var v1 :: Id
v1) (Var v2 :: Id
v2) = Id
v1 Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
v2
go (Lit lit1 :: Literal
lit1) (Lit lit2 :: Literal
lit2) = Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2
go (Type t1 :: Type
t1) (Type t2 :: Type
t2) = Type
t1 Type -> Type -> Bool
`eqType` Type
t2
go (Coercion c1 :: Coercion
c1) (Coercion c2 :: Coercion
c2) = Coercion
c1 Coercion -> Coercion -> Bool
`eqCoercion` Coercion
c2
go (App f1 :: Expr b
f1 a1 :: Expr b
a1) (App f2 :: Expr b
f2 a2 :: Expr b
a2)
= Expr b
f1 Expr b -> Expr b -> Bool
`go_s` Expr b
f2 Bool -> Bool -> Bool
&& Expr b
a1 Expr b -> Expr b -> Bool
`go_s` Expr b
a2
go (Cast e1 :: Expr b
e1 t1 :: Coercion
t1) (Cast e2 :: Expr b
e2 t2 :: Coercion
t2)
= Expr b
e1 Expr b -> Expr b -> Bool
`go_s` Expr b
e2 Bool -> Bool -> Bool
&& Coercion
t1 Coercion -> Coercion -> Bool
`eqCoercion` Coercion
t2
go (Tick t1 :: Tickish Id
t1 e1 :: Expr b
e1) (Tick t2 :: Tickish Id
t2 e2 :: Expr b
e2)
= Tickish Id
t1 Tickish Id -> Tickish Id -> Bool
forall a. Eq a => a -> a -> Bool
== Tickish Id
t2 Bool -> Bool -> Bool
&& Expr b
e1 Expr b -> Expr b -> Bool
`go_s` Expr b
e2
go _ _ = Bool
False
{-# INLINE go #-}
{-# INLINE cheapEqExpr' #-}
exprIsBig :: Expr b -> Bool
exprIsBig :: Expr b -> Bool
exprIsBig (Lit _) = Bool
False
exprIsBig (Var _) = Bool
False
exprIsBig (Type _) = Bool
False
exprIsBig (Coercion _) = Bool
False
exprIsBig (Lam _ e :: Expr b
e) = Expr b -> Bool
forall b. Expr b -> Bool
exprIsBig Expr b
e
exprIsBig (App f :: Expr b
f a :: Expr b
a) = Expr b -> Bool
forall b. Expr b -> Bool
exprIsBig Expr b
f Bool -> Bool -> Bool
|| Expr b -> Bool
forall b. Expr b -> Bool
exprIsBig Expr b
a
exprIsBig (Cast e :: Expr b
e _) = Expr b -> Bool
forall b. Expr b -> Bool
exprIsBig Expr b
e
exprIsBig (Tick _ e :: Expr b
e) = Expr b -> Bool
forall b. Expr b -> Bool
exprIsBig Expr b
e
exprIsBig _ = Bool
True
eqExpr :: InScopeSet -> CoreExpr -> CoreExpr -> Bool
eqExpr :: InScopeSet -> CoreExpr -> CoreExpr -> Bool
eqExpr in_scope :: InScopeSet
in_scope e1 :: CoreExpr
e1 e2 :: CoreExpr
e2
= RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (InScopeSet -> RnEnv2
mkRnEnv2 InScopeSet
in_scope) CoreExpr
e1 CoreExpr
e2
where
go :: RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go env :: RnEnv2
env (Var v1 :: Id
v1) (Var v2 :: Id
v2)
| RnEnv2 -> Id -> Id
rnOccL RnEnv2
env Id
v1 Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== RnEnv2 -> Id -> Id
rnOccR RnEnv2
env Id
v2
= Bool
True
go _ (Lit lit1 :: Literal
lit1) (Lit lit2 :: Literal
lit2) = Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2
go env :: RnEnv2
env (Type t1 :: Type
t1) (Type t2 :: Type
t2) = RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2
go env :: RnEnv2
env (Coercion co1 :: Coercion
co1) (Coercion co2 :: Coercion
co2) = RnEnv2 -> Coercion -> Coercion -> Bool
eqCoercionX RnEnv2
env Coercion
co1 Coercion
co2
go env :: RnEnv2
env (Cast e1 :: CoreExpr
e1 co1 :: Coercion
co1) (Cast e2 :: CoreExpr
e2 co2 :: Coercion
co2) = RnEnv2 -> Coercion -> Coercion -> Bool
eqCoercionX RnEnv2
env Coercion
co1 Coercion
co2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
e1 CoreExpr
e2
go env :: RnEnv2
env (App f1 :: CoreExpr
f1 a1 :: CoreExpr
a1) (App f2 :: CoreExpr
f2 a2 :: CoreExpr
a2) = RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
f1 CoreExpr
f2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
a1 CoreExpr
a2
go env :: RnEnv2
env (Tick n1 :: Tickish Id
n1 e1 :: CoreExpr
e1) (Tick n2 :: Tickish Id
n2 e2 :: CoreExpr
e2) = RnEnv2 -> Tickish Id -> Tickish Id -> Bool
eqTickish RnEnv2
env Tickish Id
n1 Tickish Id
n2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
e1 CoreExpr
e2
go env :: RnEnv2
env (Lam b1 :: Id
b1 e1 :: CoreExpr
e1) (Lam b2 :: Id
b2 e2 :: CoreExpr
e2)
= RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env (Id -> Type
varType Id
b1) (Id -> Type
varType Id
b2)
Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
b1 Id
b2) CoreExpr
e1 CoreExpr
e2
go env :: RnEnv2
env (Let (NonRec v1 :: Id
v1 r1 :: CoreExpr
r1) e1 :: CoreExpr
e1) (Let (NonRec v2 :: Id
v2 r2 :: CoreExpr
r2) e2 :: CoreExpr
e2)
= RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
r1 CoreExpr
r2
Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
v1 Id
v2) CoreExpr
e1 CoreExpr
e2
go env :: RnEnv2
env (Let (Rec ps1 :: [(Id, CoreExpr)]
ps1) e1 :: CoreExpr
e1) (Let (Rec ps2 :: [(Id, CoreExpr)]
ps2) e2 :: CoreExpr
e2)
= [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [(Id, CoreExpr)]
ps1 [(Id, CoreExpr)]
ps2
Bool -> Bool -> Bool
&& (CoreExpr -> CoreExpr -> Bool) -> [CoreExpr] -> [CoreExpr] -> Bool
forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
all2 (RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env') [CoreExpr]
rs1 [CoreExpr]
rs2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env' CoreExpr
e1 CoreExpr
e2
where
(bs1 :: [Id]
bs1,rs1 :: [CoreExpr]
rs1) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
ps1
(bs2 :: [Id]
bs2,rs2 :: [CoreExpr]
rs2) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
ps2
env' :: RnEnv2
env' = RnEnv2 -> [Id] -> [Id] -> RnEnv2
rnBndrs2 RnEnv2
env [Id]
bs1 [Id]
bs2
go env :: RnEnv2
env (Case e1 :: CoreExpr
e1 b1 :: Id
b1 t1 :: Type
t1 a1 :: [CoreAlt]
a1) (Case e2 :: CoreExpr
e2 b2 :: Id
b2 t2 :: Type
t2 a2 :: [CoreAlt]
a2)
| [CoreAlt] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreAlt]
a1
= [CoreAlt] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreAlt]
a2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
e1 CoreExpr
e2 Bool -> Bool -> Bool
&& RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2
| Bool
otherwise
= RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
e1 CoreExpr
e2 Bool -> Bool -> Bool
&& (CoreAlt -> CoreAlt -> Bool) -> [CoreAlt] -> [CoreAlt] -> Bool
forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
all2 (RnEnv2 -> CoreAlt -> CoreAlt -> Bool
go_alt (RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
b1 Id
b2)) [CoreAlt]
a1 [CoreAlt]
a2
go _ _ _ = Bool
False
go_alt :: RnEnv2 -> CoreAlt -> CoreAlt -> Bool
go_alt env :: RnEnv2
env (c1 :: AltCon
c1, bs1 :: [Id]
bs1, e1 :: CoreExpr
e1) (c2 :: AltCon
c2, bs2 :: [Id]
bs2, e2 :: CoreExpr
e2)
= AltCon
c1 AltCon -> AltCon -> Bool
forall a. Eq a => a -> a -> Bool
== AltCon
c2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (RnEnv2 -> [Id] -> [Id] -> RnEnv2
rnBndrs2 RnEnv2
env [Id]
bs1 [Id]
bs2) CoreExpr
e1 CoreExpr
e2
eqTickish :: RnEnv2 -> Tickish Id -> Tickish Id -> Bool
eqTickish :: RnEnv2 -> Tickish Id -> Tickish Id -> Bool
eqTickish env :: RnEnv2
env (Breakpoint lid :: Int
lid lids :: [Id]
lids) (Breakpoint rid :: Int
rid rids :: [Id]
rids)
= Int
lid Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rid Bool -> Bool -> Bool
&& (Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (RnEnv2 -> Id -> Id
rnOccL RnEnv2
env) [Id]
lids [Id] -> [Id] -> Bool
forall a. Eq a => a -> a -> Bool
== (Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (RnEnv2 -> Id -> Id
rnOccR RnEnv2
env) [Id]
rids
eqTickish _ l :: Tickish Id
l r :: Tickish Id
r = Tickish Id
l Tickish Id -> Tickish Id -> Bool
forall a. Eq a => a -> a -> Bool
== Tickish Id
r
diffExpr :: Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr :: Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr _ env :: RnEnv2
env (Var v1 :: Id
v1) (Var v2 :: Id
v2) | RnEnv2 -> Id -> Id
rnOccL RnEnv2
env Id
v1 Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== RnEnv2 -> Id -> Id
rnOccR RnEnv2
env Id
v2 = []
diffExpr _ _ (Lit lit1 :: Literal
lit1) (Lit lit2 :: Literal
lit2) | Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2 = []
diffExpr _ env :: RnEnv2
env (Type t1 :: Type
t1) (Type t2 :: Type
t2) | RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2 = []
diffExpr _ env :: RnEnv2
env (Coercion co1 :: Coercion
co1) (Coercion co2 :: Coercion
co2)
| RnEnv2 -> Coercion -> Coercion -> Bool
eqCoercionX RnEnv2
env Coercion
co1 Coercion
co2 = []
diffExpr top :: Bool
top env :: RnEnv2
env (Cast e1 :: CoreExpr
e1 co1 :: Coercion
co1) (Cast e2 :: CoreExpr
e2 co2 :: Coercion
co2)
| RnEnv2 -> Coercion -> Coercion -> Bool
eqCoercionX RnEnv2
env Coercion
co1 Coercion
co2 = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr top :: Bool
top env :: RnEnv2
env (Tick n1 :: Tickish Id
n1 e1 :: CoreExpr
e1) e2 :: CoreExpr
e2
| Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Id
n1) = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr top :: Bool
top env :: RnEnv2
env e1 :: CoreExpr
e1 (Tick n2 :: Tickish Id
n2 e2 :: CoreExpr
e2)
| Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Id
n2) = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr top :: Bool
top env :: RnEnv2
env (Tick n1 :: Tickish Id
n1 e1 :: CoreExpr
e1) (Tick n2 :: Tickish Id
n2 e2 :: CoreExpr
e2)
| RnEnv2 -> Tickish Id -> Tickish Id -> Bool
eqTickish RnEnv2
env Tickish Id
n1 Tickish Id
n2 = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr _ _ (App (App (Var absent :: Id
absent) _) _)
(App (App (Var absent2 :: Id
absent2) _) _)
| Id -> Bool
isBottomingId Id
absent Bool -> Bool -> Bool
&& Id -> Bool
isBottomingId Id
absent2 = []
diffExpr top :: Bool
top env :: RnEnv2
env (App f1 :: CoreExpr
f1 a1 :: CoreExpr
a1) (App f2 :: CoreExpr
f2 a2 :: CoreExpr
a2)
= Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
f1 CoreExpr
f2 [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++ Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
a1 CoreExpr
a2
diffExpr top :: Bool
top env :: RnEnv2
env (Lam b1 :: Id
b1 e1 :: CoreExpr
e1) (Lam b2 :: Id
b2 e2 :: CoreExpr
e2)
| RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env (Id -> Type
varType Id
b1) (Id -> Type
varType Id
b2)
= Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top (RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
b1 Id
b2) CoreExpr
e1 CoreExpr
e2
diffExpr top :: Bool
top env :: RnEnv2
env (Let bs1 :: Bind Id
bs1 e1 :: CoreExpr
e1) (Let bs2 :: Bind Id
bs2 e2 :: CoreExpr
e2)
= let (ds :: [SDoc]
ds, env' :: RnEnv2
env') = Bool
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds Bool
top RnEnv2
env ([Bind Id] -> [(Id, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds [Bind Id
bs1]) ([Bind Id] -> [(Id, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds [Bind Id
bs2])
in [SDoc]
ds [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++ Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env' CoreExpr
e1 CoreExpr
e2
diffExpr top :: Bool
top env :: RnEnv2
env (Case e1 :: CoreExpr
e1 b1 :: Id
b1 t1 :: Type
t1 a1 :: [CoreAlt]
a1) (Case e2 :: CoreExpr
e2 b2 :: Id
b2 t2 :: Type
t2 a2 :: [CoreAlt]
a2)
| [CoreAlt] -> [CoreAlt] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [CoreAlt]
a1 [CoreAlt]
a2 Bool -> Bool -> Bool
&& Bool -> Bool
not ([CoreAlt] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreAlt]
a1) Bool -> Bool -> Bool
|| RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2
= Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2 [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++ [[SDoc]] -> [SDoc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((CoreAlt -> CoreAlt -> [SDoc])
-> [CoreAlt] -> [CoreAlt] -> [[SDoc]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith CoreAlt -> CoreAlt -> [SDoc]
forall a.
(Eq a, Outputable a) =>
(a, [Id], CoreExpr) -> (a, [Id], CoreExpr) -> [SDoc]
diffAlt [CoreAlt]
a1 [CoreAlt]
a2)
where env' :: RnEnv2
env' = RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
b1 Id
b2
diffAlt :: (a, [Id], CoreExpr) -> (a, [Id], CoreExpr) -> [SDoc]
diffAlt (c1 :: a
c1, bs1 :: [Id]
bs1, e1 :: CoreExpr
e1) (c2 :: a
c2, bs2 :: [Id]
bs2, e2 :: CoreExpr
e2)
| a
c1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
c2 = [String -> SDoc
text "alt-cons " SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
c1 SDoc -> SDoc -> SDoc
<> String -> SDoc
text " /= " SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
c2]
| Bool
otherwise = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top (RnEnv2 -> [Id] -> [Id] -> RnEnv2
rnBndrs2 RnEnv2
env' [Id]
bs1 [Id]
bs2) CoreExpr
e1 CoreExpr
e2
diffExpr _ _ e1 :: CoreExpr
e1 e2 :: CoreExpr
e2
= [[SDoc] -> SDoc
fsep [CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e1, String -> SDoc
text "/=", CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e2]]
diffBinds :: Bool -> RnEnv2 -> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds :: Bool
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds top :: Bool
top env :: RnEnv2
env binds1 :: [(Id, CoreExpr)]
binds1 = Int
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
go ([(Id, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Id, CoreExpr)]
binds1) RnEnv2
env [(Id, CoreExpr)]
binds1
where go :: Int
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
go _ env :: RnEnv2
env [] []
= ([], RnEnv2
env)
go fuel :: Int
fuel env :: RnEnv2
env binds1 :: [(Id, CoreExpr)]
binds1 binds2 :: [(Id, CoreExpr)]
binds2
| [(Id, CoreExpr)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Id, CoreExpr)]
binds1 Bool -> Bool -> Bool
|| [(Id, CoreExpr)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Id, CoreExpr)]
binds2
= (RnEnv2 -> [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> [SDoc]
warn RnEnv2
env [(Id, CoreExpr)]
binds1 [(Id, CoreExpr)]
binds2, RnEnv2
env)
| Int
fuel Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
= if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ RnEnv2
env RnEnv2 -> Id -> Bool
`inRnEnvL` (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst ([(Id, CoreExpr)] -> (Id, CoreExpr)
forall a. [a] -> a
head [(Id, CoreExpr)]
binds1)
then let env' :: RnEnv2
env' = ([Id] -> [Id] -> RnEnv2) -> ([Id], [Id]) -> RnEnv2
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (RnEnv2 -> [Id] -> [Id] -> RnEnv2
rnBndrs2 RnEnv2
env) (([Id], [Id]) -> RnEnv2) -> ([Id], [Id]) -> RnEnv2
forall a b. (a -> b) -> a -> b
$ [(Id, Id)] -> ([Id], [Id])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Id, Id)] -> ([Id], [Id])) -> [(Id, Id)] -> ([Id], [Id])
forall a b. (a -> b) -> a -> b
$
[Id] -> [Id] -> [(Id, Id)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([Id] -> [Id]
forall a. Ord a => [a] -> [a]
sort ([Id] -> [Id]) -> [Id] -> [Id]
forall a b. (a -> b) -> a -> b
$ ((Id, CoreExpr) -> Id) -> [(Id, CoreExpr)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreExpr)]
binds1) ([Id] -> [Id]
forall a. Ord a => [a] -> [a]
sort ([Id] -> [Id]) -> [Id] -> [Id]
forall a b. (a -> b) -> a -> b
$ ((Id, CoreExpr) -> Id) -> [(Id, CoreExpr)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreExpr)]
binds2)
in Int
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
go ([(Id, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Id, CoreExpr)]
binds1) RnEnv2
env' [(Id, CoreExpr)]
binds1 [(Id, CoreExpr)]
binds2
else (RnEnv2 -> [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> [SDoc]
warn RnEnv2
env [(Id, CoreExpr)]
binds1 [(Id, CoreExpr)]
binds2, RnEnv2
env)
go fuel :: Int
fuel env :: RnEnv2
env ((bndr1 :: Id
bndr1,expr1 :: CoreExpr
expr1):binds1 :: [(Id, CoreExpr)]
binds1) binds2 :: [(Id, CoreExpr)]
binds2
| let matchExpr :: (Id, CoreExpr) -> Bool
matchExpr (bndr :: Id
bndr,expr :: CoreExpr
expr) =
(Bool -> Bool
not Bool
top Bool -> Bool -> Bool
|| [SDoc] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (RnEnv2 -> Id -> Id -> [SDoc]
diffIdInfo RnEnv2
env Id
bndr Id
bndr1)) Bool -> Bool -> Bool
&&
[SDoc] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top (RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
bndr1 Id
bndr) CoreExpr
expr1 CoreExpr
expr)
, (binds2l :: [(Id, CoreExpr)]
binds2l, (bndr2 :: Id
bndr2,_):binds2r :: [(Id, CoreExpr)]
binds2r) <- ((Id, CoreExpr) -> Bool)
-> [(Id, CoreExpr)] -> ([(Id, CoreExpr)], [(Id, CoreExpr)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Id, CoreExpr) -> Bool
matchExpr [(Id, CoreExpr)]
binds2
= Int
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
go ([(Id, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Id, CoreExpr)]
binds1) (RnEnv2 -> Id -> Id -> RnEnv2
rnBndr2 RnEnv2
env Id
bndr1 Id
bndr2)
[(Id, CoreExpr)]
binds1 ([(Id, CoreExpr)]
binds2l [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. [a] -> [a] -> [a]
++ [(Id, CoreExpr)]
binds2r)
| Bool
otherwise
= Int
-> RnEnv2
-> [(Id, CoreExpr)]
-> [(Id, CoreExpr)]
-> ([SDoc], RnEnv2)
go (Int
fuelInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) RnEnv2
env ([(Id, CoreExpr)]
binds1[(Id, CoreExpr)] -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. [a] -> [a] -> [a]
++[(Id
bndr1,CoreExpr
expr1)]) [(Id, CoreExpr)]
binds2
go _ _ _ _ = String -> ([SDoc], RnEnv2)
forall a. String -> a
panic "diffBinds: impossible"
warn :: RnEnv2 -> [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> [SDoc]
warn env :: RnEnv2
env binds1 :: [(Id, CoreExpr)]
binds1 binds2 :: [(Id, CoreExpr)]
binds2 =
(((Id, CoreExpr), (Id, CoreExpr)) -> [SDoc])
-> [((Id, CoreExpr), (Id, CoreExpr))] -> [SDoc]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((Id, CoreExpr) -> (Id, CoreExpr) -> [SDoc])
-> ((Id, CoreExpr), (Id, CoreExpr)) -> [SDoc]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (RnEnv2 -> (Id, CoreExpr) -> (Id, CoreExpr) -> [SDoc]
diffBind RnEnv2
env)) ([(Id, CoreExpr)]
-> [(Id, CoreExpr)] -> [((Id, CoreExpr), (Id, CoreExpr))]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Id, CoreExpr)]
binds1' [(Id, CoreExpr)]
binds2') [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++
String -> [(Id, CoreExpr)] -> [SDoc]
forall b. OutputableBndr b => String -> [(b, Expr b)] -> [SDoc]
unmatched "unmatched left-hand:" (Int -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. Int -> [a] -> [a]
drop Int
l [(Id, CoreExpr)]
binds1') [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++
String -> [(Id, CoreExpr)] -> [SDoc]
forall b. OutputableBndr b => String -> [(b, Expr b)] -> [SDoc]
unmatched "unmatched right-hand:" (Int -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. Int -> [a] -> [a]
drop Int
l [(Id, CoreExpr)]
binds2')
where binds1' :: [(Id, CoreExpr)]
binds1' = ((Id, CoreExpr) -> (Id, CoreExpr) -> Ordering)
-> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((Id, CoreExpr) -> Id)
-> (Id, CoreExpr) -> (Id, CoreExpr) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst) [(Id, CoreExpr)]
binds1
binds2' :: [(Id, CoreExpr)]
binds2' = ((Id, CoreExpr) -> (Id, CoreExpr) -> Ordering)
-> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((Id, CoreExpr) -> Id)
-> (Id, CoreExpr) -> (Id, CoreExpr) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst) [(Id, CoreExpr)]
binds2
l :: Int
l = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min ([(Id, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Id, CoreExpr)]
binds1') ([(Id, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Id, CoreExpr)]
binds2')
unmatched :: String -> [(b, Expr b)] -> [SDoc]
unmatched _ [] = []
unmatched txt :: String
txt bs :: [(b, Expr b)]
bs = [String -> SDoc
text String
txt SDoc -> SDoc -> SDoc
$$ Bind b -> SDoc
forall a. Outputable a => a -> SDoc
ppr ([(b, Expr b)] -> Bind b
forall b. [(b, Expr b)] -> Bind b
Rec [(b, Expr b)]
bs)]
diffBind :: RnEnv2 -> (Id, CoreExpr) -> (Id, CoreExpr) -> [SDoc]
diffBind env :: RnEnv2
env (bndr1 :: Id
bndr1,expr1 :: CoreExpr
expr1) (bndr2 :: Id
bndr2,expr2 :: CoreExpr
expr2)
| ds :: [SDoc]
ds@(_:_) <- Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
expr1 CoreExpr
expr2
= String -> Id -> Id -> [SDoc] -> [SDoc]
locBind "in binding" Id
bndr1 Id
bndr2 [SDoc]
ds
| Bool
otherwise
= RnEnv2 -> Id -> Id -> [SDoc]
diffIdInfo RnEnv2
env Id
bndr1 Id
bndr2
diffIdInfo :: RnEnv2 -> Var -> Var -> [SDoc]
diffIdInfo :: RnEnv2 -> Id -> Id -> [SDoc]
diffIdInfo env :: RnEnv2
env bndr1 :: Id
bndr1 bndr2 :: Id
bndr2
| IdInfo -> Int
arityInfo IdInfo
info1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> Int
arityInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> CafInfo
cafInfo IdInfo
info1 CafInfo -> CafInfo -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> CafInfo
cafInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> OneShotInfo
oneShotInfo IdInfo
info1 OneShotInfo -> OneShotInfo -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> OneShotInfo
oneShotInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> InlinePragma
inlinePragInfo IdInfo
info1 InlinePragma -> InlinePragma -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> InlinePragma
inlinePragInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> OccInfo
occInfo IdInfo
info1 OccInfo -> OccInfo -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> OccInfo
occInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> Demand
demandInfo IdInfo
info1 Demand -> Demand -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> Demand
demandInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> Int
callArityInfo IdInfo
info1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> Int
callArityInfo IdInfo
info2
Bool -> Bool -> Bool
&& IdInfo -> LevityInfo
levityInfo IdInfo
info1 LevityInfo -> LevityInfo -> Bool
forall a. Eq a => a -> a -> Bool
== IdInfo -> LevityInfo
levityInfo IdInfo
info2
= String -> Id -> Id -> [SDoc] -> [SDoc]
locBind "in unfolding of" Id
bndr1 Id
bndr2 ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$
RnEnv2 -> Unfolding -> Unfolding -> [SDoc]
diffUnfold RnEnv2
env (IdInfo -> Unfolding
unfoldingInfo IdInfo
info1) (IdInfo -> Unfolding
unfoldingInfo IdInfo
info2)
| Bool
otherwise
= String -> Id -> Id -> [SDoc] -> [SDoc]
locBind "in Id info of" Id
bndr1 Id
bndr2
[[SDoc] -> SDoc
fsep [BindingSite -> Id -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Id
bndr1, String -> SDoc
text "/=", BindingSite -> Id -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Id
bndr2]]
where info1 :: IdInfo
info1 = HasDebugCallStack => Id -> IdInfo
Id -> IdInfo
idInfo Id
bndr1; info2 :: IdInfo
info2 = HasDebugCallStack => Id -> IdInfo
Id -> IdInfo
idInfo Id
bndr2
diffUnfold :: RnEnv2 -> Unfolding -> Unfolding -> [SDoc]
diffUnfold :: RnEnv2 -> Unfolding -> Unfolding -> [SDoc]
diffUnfold _ NoUnfolding NoUnfolding = []
diffUnfold _ BootUnfolding BootUnfolding = []
diffUnfold _ (OtherCon cs1 :: [AltCon]
cs1) (OtherCon cs2 :: [AltCon]
cs2) | [AltCon]
cs1 [AltCon] -> [AltCon] -> Bool
forall a. Eq a => a -> a -> Bool
== [AltCon]
cs2 = []
diffUnfold env :: RnEnv2
env (DFunUnfolding bs1 :: [Id]
bs1 c1 :: DataCon
c1 a1 :: [CoreExpr]
a1)
(DFunUnfolding bs2 :: [Id]
bs2 c2 :: DataCon
c2 a2 :: [CoreExpr]
a2)
| DataCon
c1 DataCon -> DataCon -> Bool
forall a. Eq a => a -> a -> Bool
== DataCon
c2 Bool -> Bool -> Bool
&& [Id] -> [Id] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [Id]
bs1 [Id]
bs2
= ((CoreExpr, CoreExpr) -> [SDoc])
-> [(CoreExpr, CoreExpr)] -> [SDoc]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((CoreExpr -> CoreExpr -> [SDoc]) -> (CoreExpr, CoreExpr) -> [SDoc]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
False RnEnv2
env')) ([CoreExpr] -> [CoreExpr] -> [(CoreExpr, CoreExpr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [CoreExpr]
a1 [CoreExpr]
a2)
where env' :: RnEnv2
env' = RnEnv2 -> [Id] -> [Id] -> RnEnv2
rnBndrs2 RnEnv2
env [Id]
bs1 [Id]
bs2
diffUnfold env :: RnEnv2
env (CoreUnfolding t1 :: CoreExpr
t1 _ _ v1 :: Bool
v1 cl1 :: Bool
cl1 wf1 :: Bool
wf1 x1 :: Bool
x1 g1 :: UnfoldingGuidance
g1)
(CoreUnfolding t2 :: CoreExpr
t2 _ _ v2 :: Bool
v2 cl2 :: Bool
cl2 wf2 :: Bool
wf2 x2 :: Bool
x2 g2 :: UnfoldingGuidance
g2)
| Bool
v1 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
v2 Bool -> Bool -> Bool
&& Bool
cl1 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
cl2
Bool -> Bool -> Bool
&& Bool
wf1 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
wf2 Bool -> Bool -> Bool
&& Bool
x1 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
x2 Bool -> Bool -> Bool
&& UnfoldingGuidance
g1 UnfoldingGuidance -> UnfoldingGuidance -> Bool
forall a. Eq a => a -> a -> Bool
== UnfoldingGuidance
g2
= Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
False RnEnv2
env CoreExpr
t1 CoreExpr
t2
diffUnfold _ uf1 :: Unfolding
uf1 uf2 :: Unfolding
uf2
= [[SDoc] -> SDoc
fsep [Unfolding -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unfolding
uf1, String -> SDoc
text "/=", Unfolding -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unfolding
uf2]]
locBind :: String -> Var -> Var -> [SDoc] -> [SDoc]
locBind :: String -> Id -> Id -> [SDoc] -> [SDoc]
locBind loc :: String
loc b1 :: Id
b1 b2 :: Id
b2 diffs :: [SDoc]
diffs = (SDoc -> SDoc) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map SDoc -> SDoc
addLoc [SDoc]
diffs
where addLoc :: SDoc -> SDoc
addLoc d :: SDoc
d = SDoc
d SDoc -> SDoc -> SDoc
$$ Int -> SDoc -> SDoc
nest 2 (SDoc -> SDoc
parens (String -> SDoc
text String
loc SDoc -> SDoc -> SDoc
<+> SDoc
bindLoc))
bindLoc :: SDoc
bindLoc | Id
b1 Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
b2 = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
b1
| Bool
otherwise = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
b1 SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '/' SDoc -> SDoc -> SDoc
<> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
b2
tryEtaReduce :: [Var] -> CoreExpr -> Maybe CoreExpr
tryEtaReduce :: [Id] -> CoreExpr -> Maybe CoreExpr
tryEtaReduce bndrs :: [Id]
bndrs body :: CoreExpr
body
= [Id] -> CoreExpr -> Coercion -> Maybe CoreExpr
go ([Id] -> [Id]
forall a. [a] -> [a]
reverse [Id]
bndrs) CoreExpr
body (Type -> Coercion
mkRepReflCo (CoreExpr -> Type
exprType CoreExpr
body))
where
incoming_arity :: Int
incoming_arity = (Id -> Bool) -> [Id] -> Int
forall a. (a -> Bool) -> [a] -> Int
count Id -> Bool
isId [Id]
bndrs
go :: [Var]
-> CoreExpr
-> Coercion
-> Maybe CoreExpr
go :: [Id] -> CoreExpr -> Coercion -> Maybe CoreExpr
go [] fun :: CoreExpr
fun co :: Coercion
co
| CoreExpr -> Bool
forall b. Expr b -> Bool
ok_fun CoreExpr
fun
, let used_vars :: VarSet
used_vars = CoreExpr -> VarSet
exprFreeVars CoreExpr
fun VarSet -> VarSet -> VarSet
`unionVarSet` Coercion -> VarSet
tyCoVarsOfCo Coercion
co
, Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Id -> VarSet -> Bool
`elemVarSet` VarSet
used_vars) [Id]
bndrs)
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
fun Coercion
co)
go bs :: [Id]
bs (Tick t :: Tickish Id
t e :: CoreExpr
e) co :: Coercion
co
| Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable Tickish Id
t
= (CoreExpr -> CoreExpr) -> Maybe CoreExpr -> Maybe CoreExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t) (Maybe CoreExpr -> Maybe CoreExpr)
-> Maybe CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Id] -> CoreExpr -> Coercion -> Maybe CoreExpr
go [Id]
bs CoreExpr
e Coercion
co
go (b :: Id
b : bs :: [Id]
bs) (App fun :: CoreExpr
fun arg :: CoreExpr
arg) co :: Coercion
co
| Just (co' :: Coercion
co', ticks :: [Tickish Id]
ticks) <- Id -> CoreExpr -> Coercion -> Maybe (Coercion, [Tickish Id])
ok_arg Id
b CoreExpr
arg Coercion
co
= (CoreExpr -> CoreExpr) -> Maybe CoreExpr -> Maybe CoreExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CoreExpr -> [Tickish Id] -> CoreExpr)
-> [Tickish Id] -> CoreExpr -> CoreExpr
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Tickish Id -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Id] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Id -> CoreExpr -> CoreExpr
mkTick) [Tickish Id]
ticks) (Maybe CoreExpr -> Maybe CoreExpr)
-> Maybe CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Id] -> CoreExpr -> Coercion -> Maybe CoreExpr
go [Id]
bs CoreExpr
fun Coercion
co'
go _ _ _ = Maybe CoreExpr
forall a. Maybe a
Nothing
ok_fun :: Expr b -> Bool
ok_fun (App fun :: Expr b
fun (Type {})) = Expr b -> Bool
ok_fun Expr b
fun
ok_fun (Cast fun :: Expr b
fun _) = Expr b -> Bool
ok_fun Expr b
fun
ok_fun (Tick _ expr :: Expr b
expr) = Expr b -> Bool
ok_fun Expr b
expr
ok_fun (Var fun_id :: Id
fun_id) = Id -> Bool
ok_fun_id Id
fun_id Bool -> Bool -> Bool
|| (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
ok_lam [Id]
bndrs
ok_fun _fun :: Expr b
_fun = Bool
False
ok_fun_id :: Id -> Bool
ok_fun_id fun :: Id
fun = Id -> Int
fun_arity Id
fun Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
incoming_arity
fun_arity :: Id -> Int
fun_arity fun :: Id
fun
| Id -> Bool
isLocalId Id
fun
, OccInfo -> Bool
isStrongLoopBreaker (Id -> OccInfo
idOccInfo Id
fun) = 0
| Int
arity Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 = Int
arity
| Unfolding -> Bool
isEvaldUnfolding (Id -> Unfolding
idUnfolding Id
fun) = 1
| Bool
otherwise = 0
where
arity :: Int
arity = Id -> Int
idArity Id
fun
ok_lam :: Id -> Bool
ok_lam v :: Id
v = Id -> Bool
isTyVar Id
v Bool -> Bool -> Bool
|| Id -> Bool
isEvVar Id
v
ok_arg :: Var
-> CoreExpr
-> Coercion
-> Maybe (Coercion
, [Tickish Var])
ok_arg :: Id -> CoreExpr -> Coercion -> Maybe (Coercion, [Tickish Id])
ok_arg bndr :: Id
bndr (Type ty :: Type
ty) co :: Coercion
co
| Just tv :: Id
tv <- Type -> Maybe Id
getTyVar_maybe Type
ty
, Id
bndr Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
tv = (Coercion, [Tickish Id]) -> Maybe (Coercion, [Tickish Id])
forall a. a -> Maybe a
Just ([Id] -> Coercion -> Coercion
mkHomoForAllCos [Id
tv] Coercion
co, [])
ok_arg bndr :: Id
bndr (Var v :: Id
v) co :: Coercion
co
| Id
bndr Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
v = let reflCo :: Coercion
reflCo = Type -> Coercion
mkRepReflCo (Id -> Type
idType Id
bndr)
in (Coercion, [Tickish Id]) -> Maybe (Coercion, [Tickish Id])
forall a. a -> Maybe a
Just (Role -> Coercion -> Coercion -> Coercion
mkFunCo Role
Representational Coercion
reflCo Coercion
co, [])
ok_arg bndr :: Id
bndr (Cast e :: CoreExpr
e co_arg :: Coercion
co_arg) co :: Coercion
co
| (ticks :: [Tickish Id]
ticks, Var v :: Id
v) <- (Tickish Id -> Bool) -> CoreExpr -> ([Tickish Id], CoreExpr)
forall b. (Tickish Id -> Bool) -> Expr b -> ([Tickish Id], Expr b)
stripTicksTop Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable CoreExpr
e
, Id
bndr Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
v
= (Coercion, [Tickish Id]) -> Maybe (Coercion, [Tickish Id])
forall a. a -> Maybe a
Just (Role -> Coercion -> Coercion -> Coercion
mkFunCo Role
Representational (Coercion -> Coercion
mkSymCo Coercion
co_arg) Coercion
co, [Tickish Id]
ticks)
ok_arg bndr :: Id
bndr (Tick t :: Tickish Id
t arg :: CoreExpr
arg) co :: Coercion
co
| Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable Tickish Id
t, Just (co' :: Coercion
co', ticks :: [Tickish Id]
ticks) <- Id -> CoreExpr -> Coercion -> Maybe (Coercion, [Tickish Id])
ok_arg Id
bndr CoreExpr
arg Coercion
co
= (Coercion, [Tickish Id]) -> Maybe (Coercion, [Tickish Id])
forall a. a -> Maybe a
Just (Coercion
co', Tickish Id
tTickish Id -> [Tickish Id] -> [Tickish Id]
forall a. a -> [a] -> [a]
:[Tickish Id]
ticks)
ok_arg _ _ _ = Maybe (Coercion, [Tickish Id])
forall a. Maybe a
Nothing
rhsIsStatic
:: Platform
-> (Name -> Bool)
-> (LitNumType -> Integer -> Maybe CoreExpr)
-> CoreExpr -> Bool
rhsIsStatic :: Platform
-> (Name -> Bool)
-> (LitNumType -> Integer -> Maybe CoreExpr)
-> CoreExpr
-> Bool
rhsIsStatic platform :: Platform
platform is_dynamic_name :: Name -> Bool
is_dynamic_name cvt_literal :: LitNumType -> Integer -> Maybe CoreExpr
cvt_literal rhs :: CoreExpr
rhs = Bool -> CoreExpr -> Bool
is_static Bool
False CoreExpr
rhs
where
is_static :: Bool
-> CoreExpr -> Bool
is_static :: Bool -> CoreExpr -> Bool
is_static False (Lam b :: Id
b e :: CoreExpr
e) = Id -> Bool
isRuntimeVar Id
b Bool -> Bool -> Bool
|| Bool -> CoreExpr -> Bool
is_static Bool
False CoreExpr
e
is_static in_arg :: Bool
in_arg (Tick n :: Tickish Id
n e :: CoreExpr
e) = Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Id
n)
Bool -> Bool -> Bool
&& Bool -> CoreExpr -> Bool
is_static Bool
in_arg CoreExpr
e
is_static in_arg :: Bool
in_arg (Cast e :: CoreExpr
e _) = Bool -> CoreExpr -> Bool
is_static Bool
in_arg CoreExpr
e
is_static _ (Coercion {}) = Bool
True
is_static in_arg :: Bool
in_arg (Lit (LitNumber nt :: LitNumType
nt i :: Integer
i _)) = case LitNumType -> Integer -> Maybe CoreExpr
cvt_literal LitNumType
nt Integer
i of
Just e :: CoreExpr
e -> Bool -> CoreExpr -> Bool
is_static Bool
in_arg CoreExpr
e
Nothing -> Bool
True
is_static _ (Lit (LitLabel {})) = Bool
False
is_static _ (Lit _) = Bool
True
is_static in_arg :: Bool
in_arg other_expr :: CoreExpr
other_expr = CoreExpr -> Int -> Bool
go CoreExpr
other_expr 0
where
go :: CoreExpr -> Int -> Bool
go (Var f :: Id
f) n_val_args :: Int
n_val_args
| (Platform -> OS
platformOS Platform
platform OS -> OS -> Bool
forall a. Eq a => a -> a -> Bool
/= OS
OSMinGW32) Bool -> Bool -> Bool
||
Bool -> Bool
not (Name -> Bool
is_dynamic_name (Id -> Name
idName Id
f))
= CheapAppFun
saturated_data_con Id
f Int
n_val_args
Bool -> Bool -> Bool
|| (Bool
in_arg Bool -> Bool -> Bool
&& Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0)
go (App f :: CoreExpr
f a :: CoreExpr
a) n_val_args :: Int
n_val_args
| CoreExpr -> Bool
forall b. Expr b -> Bool
isTypeArg CoreExpr
a = CoreExpr -> Int -> Bool
go CoreExpr
f Int
n_val_args
| Bool -> Bool
not Bool
in_arg Bool -> Bool -> Bool
&& Bool -> CoreExpr -> Bool
is_static Bool
True CoreExpr
a = CoreExpr -> Int -> Bool
go CoreExpr
f (Int
n_val_args Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
go (Tick n :: Tickish Id
n f :: CoreExpr
f) n_val_args :: Int
n_val_args = Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Id
n) Bool -> Bool -> Bool
&& CoreExpr -> Int -> Bool
go CoreExpr
f Int
n_val_args
go (Cast e :: CoreExpr
e _) n_val_args :: Int
n_val_args = CoreExpr -> Int -> Bool
go CoreExpr
e Int
n_val_args
go _ _ = Bool
False
saturated_data_con :: CheapAppFun
saturated_data_con f :: Id
f n_val_args :: Int
n_val_args
= case Id -> Maybe DataCon
isDataConWorkId_maybe Id
f of
Just dc :: DataCon
dc -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== DataCon -> Int
dataConRepArity DataCon
dc
Nothing -> Bool
False
isEmptyTy :: Type -> Bool
isEmptyTy :: Type -> Bool
isEmptyTy ty :: Type
ty
| Just (tc :: TyCon
tc, inst_tys :: [Type]
inst_tys) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty
, Just dcs :: [DataCon]
dcs <- TyCon -> Maybe [DataCon]
tyConDataCons_maybe TyCon
tc
, (DataCon -> Bool) -> [DataCon] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ([Type] -> DataCon -> Bool
dataConCannotMatch [Type]
inst_tys) [DataCon]
dcs
= Bool
True
| Bool
otherwise
= Bool
False
collectMakeStaticArgs
:: CoreExpr -> Maybe (CoreExpr, Type, CoreExpr, CoreExpr)
collectMakeStaticArgs :: CoreExpr -> Maybe (CoreExpr, Type, CoreExpr, CoreExpr)
collectMakeStaticArgs e :: CoreExpr
e
| (fun :: CoreExpr
fun@(Var b :: Id
b), [Type t :: Type
t, loc :: CoreExpr
loc, arg :: CoreExpr
arg], _) <- (Tickish Id -> Bool)
-> CoreExpr -> (CoreExpr, [CoreExpr], [Tickish Id])
forall b.
(Tickish Id -> Bool) -> Expr b -> (Expr b, [Expr b], [Tickish Id])
collectArgsTicks (Bool -> Tickish Id -> Bool
forall a b. a -> b -> a
const Bool
True) CoreExpr
e
, Id -> Name
idName Id
b Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
makeStaticName = (CoreExpr, Type, CoreExpr, CoreExpr)
-> Maybe (CoreExpr, Type, CoreExpr, CoreExpr)
forall a. a -> Maybe a
Just (CoreExpr
fun, Type
t, CoreExpr
loc, CoreExpr
arg)
collectMakeStaticArgs _ = Maybe (CoreExpr, Type, CoreExpr, CoreExpr)
forall a. Maybe a
Nothing
isJoinBind :: CoreBind -> Bool
isJoinBind :: Bind Id -> Bool
isJoinBind (NonRec b :: Id
b _) = Id -> Bool
isJoinId Id
b
isJoinBind (Rec ((b :: Id
b, _) : _)) = Id -> Bool
isJoinId Id
b
isJoinBind _ = Bool
False