{-# LANGUAGE CPP #-}
module GHC.Core.Utils (
mkCast,
mkTick, mkTicks, mkTickNoHNF, tickHNFArgs,
bindNonRec, needsCaseBinding,
mkAltExpr, mkDefaultCase, mkSingleAltCase,
findDefault, addDefault, findAlt, isDefaultAlt,
mergeAlts, trimConArgs,
filterAlts, combineIdenticalAlts, refineDefaultAlt,
scaleAltsBy,
exprType, coreAltType, coreAltsType, mkLamType, mkLamTypes,
mkFunctionType,
isExprLevPoly,
exprIsDupable, exprIsTrivial, getIdFromTrivialExpr, exprIsDeadEnd,
getIdFromTrivialExpr_maybe,
exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun,
exprIsHNF, exprOkForSpeculation, exprOkForSideEffects, exprIsWorkFree,
exprIsConLike,
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,
isUnsafeEqualityProof,
dumpIdInfoOfProgram
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Platform
import GHC.Core
import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofName )
import GHC.Core.Ppr
import GHC.Core.FVs( exprFreeVars )
import GHC.Types.Var
import GHC.Types.SrcLoc
import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.Name
import GHC.Types.Literal
import GHC.Core.DataCon
import GHC.Builtin.PrimOps
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Builtin.Names( absentErrorIdKey )
import GHC.Core.Type as Type
import GHC.Core.Predicate
import GHC.Core.TyCo.Rep( TyCoBinder(..), TyBinder )
import GHC.Core.Coercion
import GHC.Core.TyCon
import GHC.Core.Multiplicity
import GHC.Types.Unique
import GHC.Utils.Outputable
import GHC.Builtin.Types.Prim
import GHC.Data.FastString
import GHC.Data.Maybe
import GHC.Data.List.SetOps( minusList )
import GHC.Types.Basic ( Arity )
import GHC.Utils.Misc
import GHC.Data.Pair
import Data.ByteString ( ByteString )
import Data.Function ( on )
import Data.List
import Data.Ord ( comparing )
import GHC.Data.OrdList
import qualified Data.Set as Set
import GHC.Types.Unique.Set
exprType :: CoreExpr -> Type
exprType :: CoreExpr -> Type
exprType (Var Var
var) = Var -> Type
idType Var
var
exprType (Lit Literal
lit) = Literal -> Type
literalType Literal
lit
exprType (Coercion CoercionR
co) = CoercionR -> Type
coercionType CoercionR
co
exprType (Let Bind Var
bind CoreExpr
body)
| NonRec Var
tv CoreExpr
rhs <- Bind Var
bind
, Type Type
ty <- CoreExpr
rhs = [Var] -> [Type] -> Type -> Type
substTyWithUnchecked [Var
tv] [Type
ty] (CoreExpr -> Type
exprType CoreExpr
body)
| Bool
otherwise = CoreExpr -> Type
exprType CoreExpr
body
exprType (Case CoreExpr
_ Var
_ Type
ty [Alt Var]
_) = Type
ty
exprType (Cast CoreExpr
_ CoercionR
co) = Pair Type -> Type
forall a. Pair a -> a
pSnd (CoercionR -> Pair Type
coercionKind CoercionR
co)
exprType (Tick Tickish Var
_ CoreExpr
e) = CoreExpr -> Type
exprType CoreExpr
e
exprType (Lam Var
binder CoreExpr
expr) = Var -> Type -> Type
mkLamType Var
binder (CoreExpr -> Type
exprType CoreExpr
expr)
exprType e :: CoreExpr
e@(App CoreExpr
_ CoreExpr
_)
= case CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
e of
(CoreExpr
fun, [CoreExpr]
args) -> CoreExpr -> Type -> [CoreExpr] -> Type
applyTypeToArgs CoreExpr
e (CoreExpr -> Type
exprType CoreExpr
fun) [CoreExpr]
args
exprType CoreExpr
other = String -> SDoc -> Type -> Type
forall a. String -> SDoc -> a -> a
pprTrace String
"exprType" (CoreExpr -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
other) Type
alphaTy
coreAltType :: CoreAlt -> Type
coreAltType :: Alt Var -> Type
coreAltType alt :: Alt Var
alt@(AltCon
_,[Var]
bs,CoreExpr
rhs)
= case [Var] -> Type -> Maybe Type
occCheckExpand [Var]
bs Type
rhs_ty of
Just Type
ty -> Type
ty
Maybe Type
Nothing -> String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreAltType" (Alt Var -> SDoc
forall a. OutputableBndr a => (AltCon, [a], Expr a) -> SDoc
pprCoreAlt Alt Var
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 :: [Alt Var] -> Type
coreAltsType (Alt Var
alt:[Alt Var]
_) = Alt Var -> Type
coreAltType Alt Var
alt
coreAltsType [] = String -> Type
forall a. String -> a
panic String
"corAltsType"
mkLamType :: Var -> Type -> Type
mkLamTypes :: [Var] -> Type -> Type
mkLamType :: Var -> Type -> Type
mkLamType Var
v Type
body_ty
| Var -> Bool
isTyVar Var
v
= Var -> ArgFlag -> Type -> Type
mkForAllTy Var
v ArgFlag
Inferred Type
body_ty
| Var -> Bool
isCoVar Var
v
, Var
v Var -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
body_ty
= Var -> ArgFlag -> Type -> Type
mkForAllTy Var
v ArgFlag
Required Type
body_ty
| Bool
otherwise
= Type -> Type -> Type -> Type
mkFunctionType (Var -> Type
varMult Var
v) (Var -> Type
varType Var
v) Type
body_ty
mkFunctionType :: Mult -> Type -> Type -> Type
mkFunctionType :: Type -> Type -> Type -> Type
mkFunctionType Type
mult Type
arg_ty Type
res_ty
| HasDebugCallStack => Type -> Bool
Type -> Bool
isPredTy Type
arg_ty
= ASSERT(eqType mult Many)
Type -> Type -> Type -> Type
mkInvisFunTy Type
mult Type
arg_ty Type
res_ty
| Bool
otherwise
= Type -> Type -> Type -> Type
mkVisFunTy Type
mult Type
arg_ty Type
res_ty
mkLamTypes :: [Var] -> Type -> Type
mkLamTypes [Var]
vs Type
ty = (Var -> Type -> Type) -> Type -> [Var] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Var -> Type -> Type
mkLamType Type
ty [Var]
vs
isExprLevPoly :: CoreExpr -> Bool
isExprLevPoly :: CoreExpr -> Bool
isExprLevPoly = CoreExpr -> Bool
go
where
go :: CoreExpr -> Bool
go (Var Var
_) = Bool
False
go (Lit Literal
_) = Bool
False
go e :: CoreExpr
e@(App CoreExpr
f CoreExpr
_) | 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 Var
_ CoreExpr
_) = Bool
False
go (Let Bind Var
_ 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 Tickish Var
_ CoreExpr
e) = CoreExpr -> Bool
go CoreExpr
e
go e :: CoreExpr
e@(Type {}) = String -> SDoc -> Bool
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"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 Var
id) = Bool -> Bool
not (Var -> Bool
isNeverLevPolyId Var
id)
go_app (Lit Literal
_) = Bool
False
go_app (App Expr b
f Expr b
_) = Expr b -> Bool
go_app Expr b
f
go_app (Lam b
_ Expr b
e) = Expr b -> Bool
go_app Expr b
e
go_app (Let Bind b
_ Expr b
e) = Expr b -> Bool
go_app Expr b
e
go_app (Case Expr b
_ b
_ Type
ty [Alt b]
_) = Type -> Bool
resultIsLevPoly Type
ty
go_app (Cast Expr b
_ CoercionR
co) = Type -> Bool
resultIsLevPoly (CoercionR -> Type
coercionRKind CoercionR
co)
go_app (Tick Tickish Var
_ 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 String
"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 String
"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 CoreExpr
e Type
op_ty [CoreExpr]
args
= Type -> [CoreExpr] -> Type
forall {b}. OutputableBndr b => Type -> [Expr b] -> Type
go Type
op_ty [CoreExpr]
args
where
go :: Type -> [Expr b] -> Type
go Type
op_ty [] = Type
op_ty
go Type
op_ty (Type Type
ty : [Expr b]
args) = Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty [Type
ty] [Expr b]
args
go Type
op_ty (Coercion CoercionR
co : [Expr b]
args) = Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty [CoercionR -> Type
mkCoercionTy CoercionR
co] [Expr b]
args
go Type
op_ty (Expr b
_ : [Expr b]
args) | Just (Type
_, Type
_, Type
res_ty) <- Type -> Maybe (Type, Type, Type)
splitFunTy_maybe Type
op_ty
= Type -> [Expr b] -> Type
go Type
res_ty [Expr b]
args
go Type
_ [Expr b]
args = String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"applyTypeToArgs" ([Expr b] -> SDoc
forall a. Outputable a => a -> SDoc
panic_msg [Expr b]
args)
go_ty_args :: Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty [Type]
rev_tys (Type Type
ty : [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 Type
op_ty [Type]
rev_tys (Coercion CoercionR
co : [Expr b]
args)
= Type -> [Type] -> [Expr b] -> Type
go_ty_args Type
op_ty (CoercionR -> Type
mkCoercionTy CoercionR
co Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
rev_tys) [Expr b]
args
go_ty_args Type
op_ty [Type]
rev_tys [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 :: a -> SDoc
panic_msg a
as = [SDoc] -> SDoc
vcat [ String -> SDoc
text String
"Expression:" SDoc -> SDoc -> SDoc
<+> CoreExpr -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
e
, String -> SDoc
text String
"Type:" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
op_ty
, String -> SDoc
text String
"Args:" SDoc -> SDoc -> SDoc
<+> [CoreExpr] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreExpr]
args
, String -> SDoc
text String
"Args':" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
as ]
mkCast :: CoreExpr -> CoercionR -> CoreExpr
mkCast :: CoreExpr -> CoercionR -> CoreExpr
mkCast CoreExpr
e CoercionR
co
| ASSERT2( coercionRole co == Representational
, text "coercion" <+> ppr co <+> ptext (sLit "passed to mkCast")
<+> ppr e <+> text "has wrong role" <+> ppr (coercionRole co) )
CoercionR -> Bool
isReflCo CoercionR
co
= CoreExpr
e
mkCast (Coercion CoercionR
e_co) CoercionR
co
| Type -> Bool
isCoVarType (CoercionR -> Type
coercionRKind CoercionR
co)
= CoercionR -> CoreExpr
forall b. CoercionR -> Expr b
Coercion (CoercionR -> CoercionR -> CoercionR
mkCoCast CoercionR
e_co CoercionR
co)
mkCast (Cast CoreExpr
expr CoercionR
co2) CoercionR
co
= WARN(let { from_ty = coercionLKind co;
to_ty2 = coercionRKind co2 } in
not (from_ty `eqType` to_ty2),
vcat ([ text "expr:" <+> ppr expr
, text "co2:" <+> ppr co2
, text "co:" <+> ppr co ]) )
CoreExpr -> CoercionR -> CoreExpr
mkCast CoreExpr
expr (CoercionR -> CoercionR -> CoercionR
mkTransCo CoercionR
co2 CoercionR
co)
mkCast (Tick Tickish Var
t CoreExpr
expr) CoercionR
co
= Tickish Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t (CoreExpr -> CoercionR -> CoreExpr
mkCast CoreExpr
expr CoercionR
co)
mkCast CoreExpr
expr CoercionR
co
= let from_ty :: Type
from_ty = CoercionR -> Type
coercionLKind CoercionR
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)
$$ callStackDoc )
(CoreExpr -> CoercionR -> CoreExpr
forall b. Expr b -> CoercionR -> Expr b
Cast CoreExpr
expr CoercionR
co)
mkTick :: Tickish Id -> CoreExpr -> CoreExpr
mkTick :: Tickish Var -> CoreExpr -> CoreExpr
mkTick Tickish Var
t 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 Var -> Bool
forall id. Tickish id -> Bool
tickishCanSplit Tickish Var
t Bool -> Bool -> Bool
&& Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace (Tickish Var -> Tickish Var
forall id. Tickish id -> Tickish id
mkNoCount Tickish Var
t) TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
/= Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
t
mkTick' :: (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr)
-> CoreExpr
-> CoreExpr
mkTick' :: (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' CoreExpr -> CoreExpr
top CoreExpr -> CoreExpr
rest CoreExpr
expr = case CoreExpr
expr of
Tick Tickish Var
t2 CoreExpr
e
| ProfNote{} <- Tickish Var
t2, ProfNote{} <- Tickish Var
t -> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest CoreExpr
expr
| Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
t2 TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
/= Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
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 Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t2) CoreExpr -> CoreExpr
rest CoreExpr
e
| Tickish Var -> Tickish Var -> Bool
forall b. Eq b => Tickish b -> Tickish b -> Bool
tickishContains Tickish Var
t Tickish Var
t2 -> (CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
mkTick' CoreExpr -> CoreExpr
top CoreExpr -> CoreExpr
rest CoreExpr
e
| Tickish Var -> Tickish Var -> Bool
forall b. Eq b => Tickish b -> Tickish b -> Bool
tickishContains Tickish Var
t2 Tickish Var
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 Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t2) CoreExpr
e
Cast CoreExpr
e CoercionR
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 -> CoercionR -> CoreExpr)
-> CoercionR -> CoreExpr -> CoreExpr
forall a b c. (a -> b -> c) -> b -> a -> c
flip CoreExpr -> CoercionR -> CoreExpr
forall b. Expr b -> CoercionR -> Expr b
Cast CoercionR
co) CoreExpr -> CoreExpr
rest CoreExpr
e
Coercion CoercionR
co -> CoercionR -> CoreExpr
forall b. CoercionR -> Expr b
Coercion CoercionR
co
Lam Var
x CoreExpr
e
| Bool -> Bool
not (Var -> Bool
isRuntimeVar Var
x) Bool -> Bool -> Bool
|| Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
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
. Var -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Var
x) CoreExpr -> CoreExpr
rest CoreExpr
e
| Bool
canSplit
-> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick (Tickish Var -> Tickish Var
forall id. Tickish id -> Tickish id
mkNoScope Tickish Var
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
$ Var -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Var
x (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Var -> CoreExpr -> CoreExpr
mkTick (Tickish Var -> Tickish Var
forall id. Tickish id -> Tickish id
mkNoCount Tickish Var
t) CoreExpr
e
App CoreExpr
f 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 Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
tTickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
==TickishPlacement
PlaceCostCentre Bool -> Bool -> Bool
|| Bool
canSplit)
-> if Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
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 Var -> CoreExpr -> CoreExpr
tickHNFArgs Tickish Var
t CoreExpr
expr
else CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick (Tickish Var -> Tickish Var
forall id. Tickish id -> Tickish id
mkNoScope Tickish Var
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 Var -> CoreExpr -> CoreExpr
tickHNFArgs (Tickish Var -> Tickish Var
forall id. Tickish id -> Tickish id
mkNoCount Tickish Var
t) CoreExpr
expr
Var Var
x
| Bool
notFunction Bool -> Bool -> Bool
&& Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
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 Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick (Tickish Var -> Tickish Var
forall id. Tickish id -> Tickish id
mkNoScope Tickish Var
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 (Var -> Type
idType Var
x))
Lit{}
| Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
t TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceCostCentre
-> CoreExpr
orig_expr
CoreExpr
_any -> CoreExpr -> CoreExpr
top (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Tickish Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr
rest CoreExpr
expr
mkTicks :: [Tickish Id] -> CoreExpr -> CoreExpr
mkTicks :: [Tickish Var] -> CoreExpr -> CoreExpr
mkTicks [Tickish Var]
ticks CoreExpr
expr = (Tickish Var -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Var] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Var -> CoreExpr -> CoreExpr
mkTick CoreExpr
expr [Tickish Var]
ticks
isSaturatedConApp :: CoreExpr -> Bool
isSaturatedConApp :: CoreExpr -> Bool
isSaturatedConApp CoreExpr
e = CoreExpr -> [CoreExpr] -> Bool
forall {b}. Expr b -> [Expr b] -> Bool
go CoreExpr
e []
where go :: Expr b -> [Expr b] -> Bool
go (App Expr b
f Expr b
a) [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 Var
fun) [Expr b]
args
= Var -> Bool
isConLikeId Var
fun Bool -> Bool -> Bool
&& Var -> Int
idArity Var
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 Expr b
f CoercionR
_) [Expr b]
as = Expr b -> [Expr b] -> Bool
go Expr b
f [Expr b]
as
go Expr b
_ [Expr b]
_ = Bool
False
mkTickNoHNF :: Tickish Id -> CoreExpr -> CoreExpr
mkTickNoHNF :: Tickish Var -> CoreExpr -> CoreExpr
mkTickNoHNF Tickish Var
t CoreExpr
e
| CoreExpr -> Bool
exprIsHNF CoreExpr
e = Tickish Var -> CoreExpr -> CoreExpr
tickHNFArgs Tickish Var
t CoreExpr
e
| Bool
otherwise = Tickish Var -> CoreExpr -> CoreExpr
mkTick Tickish Var
t CoreExpr
e
tickHNFArgs :: Tickish Id -> CoreExpr -> CoreExpr
tickHNFArgs :: Tickish Var -> CoreExpr -> CoreExpr
tickHNFArgs Tickish Var
t CoreExpr
e = Tickish Var -> CoreExpr -> CoreExpr
push Tickish Var
t CoreExpr
e
where
push :: Tickish Var -> CoreExpr -> CoreExpr
push Tickish Var
t (App CoreExpr
f (Type Type
u)) = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (Tickish Var -> CoreExpr -> CoreExpr
push Tickish Var
t CoreExpr
f) (Type -> CoreExpr
forall b. Type -> Expr b
Type Type
u)
push Tickish Var
t (App CoreExpr
f CoreExpr
arg) = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (Tickish Var -> CoreExpr -> CoreExpr
push Tickish Var
t CoreExpr
f) (Tickish Var -> CoreExpr -> CoreExpr
mkTick Tickish Var
t CoreExpr
arg)
push Tickish Var
_t CoreExpr
e = CoreExpr
e
stripTicksTop :: (Tickish Id -> Bool) -> Expr b -> ([Tickish Id], Expr b)
stripTicksTop :: forall b.
(Tickish Var -> Bool) -> Expr b -> ([Tickish Var], Expr b)
stripTicksTop Tickish Var -> Bool
p = [Tickish Var] -> Expr b -> ([Tickish Var], Expr b)
forall {b}. [Tickish Var] -> Expr b -> ([Tickish Var], Expr b)
go []
where go :: [Tickish Var] -> Expr b -> ([Tickish Var], Expr b)
go [Tickish Var]
ts (Tick Tickish Var
t Expr b
e) | Tickish Var -> Bool
p Tickish Var
t = [Tickish Var] -> Expr b -> ([Tickish Var], Expr b)
go (Tickish Var
tTickish Var -> [Tickish Var] -> [Tickish Var]
forall a. a -> [a] -> [a]
:[Tickish Var]
ts) Expr b
e
go [Tickish Var]
ts Expr b
other = ([Tickish Var] -> [Tickish Var]
forall a. [a] -> [a]
reverse [Tickish Var]
ts, Expr b
other)
stripTicksTopE :: (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksTopE :: forall b. (Tickish Var -> Bool) -> Expr b -> Expr b
stripTicksTopE Tickish Var -> Bool
p = Expr b -> Expr b
forall {b}. Expr b -> Expr b
go
where go :: Expr b -> Expr b
go (Tick Tickish Var
t Expr b
e) | Tickish Var -> Bool
p Tickish Var
t = Expr b -> Expr b
go Expr b
e
go Expr b
other = Expr b
other
stripTicksTopT :: (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksTopT :: forall b. (Tickish Var -> Bool) -> Expr b -> [Tickish Var]
stripTicksTopT Tickish Var -> Bool
p = [Tickish Var] -> Expr b -> [Tickish Var]
forall {b}. [Tickish Var] -> Expr b -> [Tickish Var]
go []
where go :: [Tickish Var] -> Expr b -> [Tickish Var]
go [Tickish Var]
ts (Tick Tickish Var
t Expr b
e) | Tickish Var -> Bool
p Tickish Var
t = [Tickish Var] -> Expr b -> [Tickish Var]
go (Tickish Var
tTickish Var -> [Tickish Var] -> [Tickish Var]
forall a. a -> [a] -> [a]
:[Tickish Var]
ts) Expr b
e
go [Tickish Var]
ts Expr b
_ = [Tickish Var]
ts
stripTicksE :: (Tickish Id -> Bool) -> Expr b -> Expr b
stripTicksE :: forall b. (Tickish Var -> Bool) -> Expr b -> Expr b
stripTicksE Tickish Var -> Bool
p 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 Expr b
e 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 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 Bind b
b 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 Expr b
e b
b Type
t [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 Expr b
e CoercionR
c) = Expr b -> CoercionR -> Expr b
forall b. Expr b -> CoercionR -> Expr b
Cast (Expr b -> Expr b
go Expr b
e) CoercionR
c
go (Tick Tickish Var
t Expr b
e)
| Tickish Var -> Bool
p Tickish Var
t = Expr b -> Expr b
go Expr b
e
| Bool
otherwise = Tickish Var -> Expr b -> Expr b
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t (Expr b -> Expr b
go Expr b
e)
go Expr b
other = Expr b
other
go_bs :: Bind b -> Bind b
go_bs (NonRec b
b 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 [(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, Expr b
e) = (b
b, Expr b -> Expr b
go Expr b
e)
go_a :: Alt b -> Alt b
go_a (AltCon
c,[b]
bs,Expr b
e) = (AltCon
c,[b]
bs, Expr b -> Expr b
go Expr b
e)
stripTicksT :: (Tickish Id -> Bool) -> Expr b -> [Tickish Id]
stripTicksT :: forall b. (Tickish Var -> Bool) -> Expr b -> [Tickish Var]
stripTicksT Tickish Var -> Bool
p Expr b
expr = OrdList (Tickish Var) -> [Tickish Var]
forall a. OrdList a -> [a]
fromOL (OrdList (Tickish Var) -> [Tickish Var])
-> OrdList (Tickish Var) -> [Tickish Var]
forall a b. (a -> b) -> a -> b
$ Expr b -> OrdList (Tickish Var)
forall {b}. Expr b -> OrdList (Tickish Var)
go Expr b
expr
where go :: Expr b -> OrdList (Tickish Var)
go (App Expr b
e Expr b
a) = Expr b -> OrdList (Tickish Var)
go Expr b
e OrdList (Tickish Var)
-> OrdList (Tickish Var) -> OrdList (Tickish Var)
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` Expr b -> OrdList (Tickish Var)
go Expr b
a
go (Lam b
_ Expr b
e) = Expr b -> OrdList (Tickish Var)
go Expr b
e
go (Let Bind b
b Expr b
e) = Bind b -> OrdList (Tickish Var)
go_bs Bind b
b OrdList (Tickish Var)
-> OrdList (Tickish Var) -> OrdList (Tickish Var)
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` Expr b -> OrdList (Tickish Var)
go Expr b
e
go (Case Expr b
e b
_ Type
_ [Alt b]
as) = Expr b -> OrdList (Tickish Var)
go Expr b
e OrdList (Tickish Var)
-> OrdList (Tickish Var) -> OrdList (Tickish Var)
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` [OrdList (Tickish Var)] -> OrdList (Tickish Var)
forall a. [OrdList a] -> OrdList a
concatOL ((Alt b -> OrdList (Tickish Var))
-> [Alt b] -> [OrdList (Tickish Var)]
forall a b. (a -> b) -> [a] -> [b]
map Alt b -> OrdList (Tickish Var)
go_a [Alt b]
as)
go (Cast Expr b
e CoercionR
_) = Expr b -> OrdList (Tickish Var)
go Expr b
e
go (Tick Tickish Var
t Expr b
e)
| Tickish Var -> Bool
p Tickish Var
t = Tickish Var
t Tickish Var -> OrdList (Tickish Var) -> OrdList (Tickish Var)
forall a. a -> OrdList a -> OrdList a
`consOL` Expr b -> OrdList (Tickish Var)
go Expr b
e
| Bool
otherwise = Expr b -> OrdList (Tickish Var)
go Expr b
e
go Expr b
_ = OrdList (Tickish Var)
forall a. OrdList a
nilOL
go_bs :: Bind b -> OrdList (Tickish Var)
go_bs (NonRec b
_ Expr b
e) = Expr b -> OrdList (Tickish Var)
go Expr b
e
go_bs (Rec [(b, Expr b)]
bs) = [OrdList (Tickish Var)] -> OrdList (Tickish Var)
forall a. [OrdList a] -> OrdList a
concatOL (((b, Expr b) -> OrdList (Tickish Var))
-> [(b, Expr b)] -> [OrdList (Tickish Var)]
forall a b. (a -> b) -> [a] -> [b]
map (b, Expr b) -> OrdList (Tickish Var)
go_b [(b, Expr b)]
bs)
go_b :: (b, Expr b) -> OrdList (Tickish Var)
go_b (b
_, Expr b
e) = Expr b -> OrdList (Tickish Var)
go Expr b
e
go_a :: Alt b -> OrdList (Tickish Var)
go_a (AltCon
_, [b]
_, Expr b
e) = Expr b -> OrdList (Tickish Var)
go Expr b
e
bindNonRec :: Id -> CoreExpr -> CoreExpr -> CoreExpr
bindNonRec :: Var -> CoreExpr -> CoreExpr -> CoreExpr
bindNonRec Var
bndr CoreExpr
rhs CoreExpr
body
| Var -> Bool
isTyVar Var
bndr = CoreExpr
let_bind
| Var -> Bool
isCoVar Var
bndr = if CoreExpr -> Bool
forall b. Expr b -> Bool
isCoArg CoreExpr
rhs then CoreExpr
let_bind
else CoreExpr
case_bind
| Var -> Bool
isJoinId Var
bndr = CoreExpr
let_bind
| Type -> CoreExpr -> Bool
needsCaseBinding (Var -> Type
idType Var
bndr) CoreExpr
rhs = CoreExpr
case_bind
| Bool
otherwise = CoreExpr
let_bind
where
case_bind :: CoreExpr
case_bind = CoreExpr -> Var -> CoreExpr -> CoreExpr
mkDefaultCase CoreExpr
rhs Var
bndr CoreExpr
body
let_bind :: CoreExpr
let_bind = Bind Var -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (Var -> CoreExpr -> Bind Var
forall b. b -> Expr b -> Bind b
NonRec Var
bndr CoreExpr
rhs) CoreExpr
body
needsCaseBinding :: Type -> CoreExpr -> Bool
needsCaseBinding :: Type -> CoreExpr -> Bool
needsCaseBinding Type
ty 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 -> [Var] -> [Type] -> CoreExpr
mkAltExpr (DataAlt DataCon
con) [Var]
args [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]
++ [Var] -> [CoreExpr]
forall b. [Var] -> [Expr b]
varsToCoreExprs [Var]
args)
mkAltExpr (LitAlt Literal
lit) [] []
= Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit
mkAltExpr (LitAlt Literal
_) [Var]
_ [Type]
_ = String -> CoreExpr
forall a. String -> a
panic String
"mkAltExpr LitAlt"
mkAltExpr AltCon
DEFAULT [Var]
_ [Type]
_ = String -> CoreExpr
forall a. String -> a
panic String
"mkAltExpr DEFAULT"
mkDefaultCase :: CoreExpr -> Id -> CoreExpr -> CoreExpr
mkDefaultCase :: CoreExpr -> Var -> CoreExpr -> CoreExpr
mkDefaultCase CoreExpr
scrut Var
case_bndr CoreExpr
body
= CoreExpr -> Var -> Type -> [Alt Var] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case CoreExpr
scrut Var
case_bndr (CoreExpr -> Type
exprType CoreExpr
body) [(AltCon
DEFAULT, [], CoreExpr
body)]
mkSingleAltCase :: CoreExpr -> Id -> AltCon -> [Var] -> CoreExpr -> CoreExpr
mkSingleAltCase :: CoreExpr -> Var -> AltCon -> [Var] -> CoreExpr -> CoreExpr
mkSingleAltCase CoreExpr
scrut Var
case_bndr AltCon
con [Var]
bndrs CoreExpr
body
= CoreExpr -> Var -> Type -> [Alt Var] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case CoreExpr
scrut Var
case_bndr Type
case_ty [(AltCon
con,[Var]
bndrs,CoreExpr
body)]
where
body_ty :: Type
body_ty = CoreExpr -> Type
exprType CoreExpr
body
case_ty :: Type
case_ty
| Just Type
body_ty' <- [Var] -> Type -> Maybe Type
occCheckExpand [Var]
bndrs Type
body_ty
= Type
body_ty'
| Bool
otherwise
= String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkSingleAltCase" (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
scrut SDoc -> SDoc -> SDoc
$$ [Var] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Var]
bndrs SDoc -> SDoc -> SDoc
$$ Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
body_ty)
findDefault :: [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault :: forall a b. [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault ((AltCon
DEFAULT,[a]
args,b
rhs) : [(AltCon, [a], b)]
alts) = ASSERT( null args ) (alts, Just rhs)
findDefault [(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 :: forall a b. [(AltCon, [a], b)] -> Maybe b -> [(AltCon, [a], b)]
addDefault [(AltCon, [a], b)]
alts Maybe b
Nothing = [(AltCon, [a], b)]
alts
addDefault [(AltCon, [a], b)]
alts (Just 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 :: forall a b. (AltCon, a, b) -> Bool
isDefaultAlt (AltCon
DEFAULT, a
_, b
_) = Bool
True
isDefaultAlt (AltCon, a, b)
_ = Bool
False
findAlt :: AltCon -> [(AltCon, a, b)] -> Maybe (AltCon, a, b)
findAlt :: forall a b. AltCon -> [(AltCon, a, b)] -> Maybe (AltCon, a, b)
findAlt AltCon
con [(AltCon, a, b)]
alts
= case [(AltCon, a, b)]
alts of
(deflt :: (AltCon, a, b)
deflt@(AltCon
DEFAULT,a
_,b
_):[(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)]
_ -> [(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 [] Maybe (AltCon, b, c)
deflt = Maybe (AltCon, b, c)
deflt
go (alt :: (AltCon, b, c)
alt@(AltCon
con1,b
_,c
_) : [(AltCon, b, c)]
alts) Maybe (AltCon, b, c)
deflt
= case AltCon
con AltCon -> AltCon -> Ordering
`cmpAltCon` AltCon
con1 of
Ordering
LT -> Maybe (AltCon, b, c)
deflt
Ordering
EQ -> (AltCon, b, c) -> Maybe (AltCon, b, c)
forall a. a -> Maybe a
Just (AltCon, b, c)
alt
Ordering
GT -> ASSERT( not (con1 == DEFAULT) ) go alts deflt
mergeAlts :: [(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts :: forall a b.
[(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts [] [(AltCon, a, b)]
as2 = [(AltCon, a, b)]
as2
mergeAlts [(AltCon, a, b)]
as1 [] = [(AltCon, a, b)]
as1
mergeAlts ((AltCon, a, b)
a1:[(AltCon, a, b)]
as1) ((AltCon, a, b)
a2:[(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
Ordering
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)
Ordering
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
Ordering
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 AltCon
DEFAULT [CoreExpr]
args = ASSERT( null args ) []
trimConArgs (LitAlt Literal
_) [CoreExpr]
args = ASSERT( null args ) []
trimConArgs (DataAlt DataCon
dc) [CoreExpr]
args = [Var] -> [CoreExpr] -> [CoreExpr]
forall b a. [b] -> [a] -> [a]
dropList (DataCon -> [Var]
dataConUnivTyVars DataCon
dc) [CoreExpr]
args
filterAlts :: TyCon
-> [Type]
-> [AltCon]
-> [(AltCon, [Var], a)]
-> ([AltCon], [(AltCon, [Var], a)])
filterAlts :: forall a.
TyCon
-> [Type]
-> [AltCon]
-> [(AltCon, [Var], a)]
-> ([AltCon], [(AltCon, [Var], a)])
filterAlts TyCon
_tycon [Type]
inst_tys [AltCon]
imposs_cons [(AltCon, [Var], a)]
alts
= ([AltCon]
imposs_deflt_cons, [(AltCon, [Var], a)] -> Maybe a -> [(AltCon, [Var], a)]
forall a b. [(AltCon, [a], b)] -> Maybe b -> [(AltCon, [a], b)]
addDefault [(AltCon, [Var], a)]
trimmed_alts Maybe a
maybe_deflt)
where
([(AltCon, [Var], a)]
alts_wo_default, Maybe a
maybe_deflt) = [(AltCon, [Var], a)] -> ([(AltCon, [Var], a)], Maybe a)
forall a b. [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault [(AltCon, [Var], a)]
alts
alt_cons :: [AltCon]
alt_cons = [AltCon
con | (AltCon
con,[Var]
_,a
_) <- [(AltCon, [Var], a)]
alts_wo_default]
trimmed_alts :: [(AltCon, [Var], a)]
trimmed_alts = ((AltCon, [Var], a) -> Bool)
-> [(AltCon, [Var], a)] -> [(AltCon, [Var], a)]
forall a. (a -> Bool) -> [a] -> [a]
filterOut ([Type] -> (AltCon, [Var], a) -> Bool
forall a b. [Type] -> (AltCon, a, b) -> Bool
impossible_alt [Type]
inst_tys) [(AltCon, [Var], 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 :: forall a b. [Type] -> (AltCon, a, b) -> Bool
impossible_alt [Type]
_ (AltCon
con, a
_, b
_) | 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 [Type]
inst_tys (DataAlt DataCon
con, a
_, b
_) = [Type] -> DataCon -> Bool
dataConCannotMatch [Type]
inst_tys DataCon
con
impossible_alt [Type]
_ (AltCon, a, b)
_ = Bool
False
refineDefaultAlt :: [Unique]
-> Mult
-> TyCon
-> [Type]
-> [AltCon]
-> [CoreAlt]
-> (Bool, [CoreAlt])
refineDefaultAlt :: [Unique]
-> Type
-> TyCon
-> [Type]
-> [AltCon]
-> [Alt Var]
-> (Bool, [Alt Var])
refineDefaultAlt [Unique]
us Type
mult TyCon
tycon [Type]
tys [AltCon]
imposs_deflt_cons [Alt Var]
all_alts
| (AltCon
DEFAULT,[Var]
_,CoreExpr
rhs) : [Alt Var]
rest_alts <- [Alt Var]
all_alts
, TyCon -> Bool
isAlgTyCon TyCon
tycon
, Bool -> Bool
not (TyCon -> Bool
isNewTyCon TyCon
tycon)
, Just [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 DataCon
con <- [AltCon]
imposs_deflt_cons]
impossible :: DataCon -> Bool
impossible 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, [Alt Var]
rest_alts)
[DataCon
con] -> (Bool
True, [Alt Var] -> [Alt Var] -> [Alt Var]
forall a b.
[(AltCon, a, b)] -> [(AltCon, a, b)] -> [(AltCon, a, b)]
mergeAlts [Alt Var]
rest_alts [(DataCon -> AltCon
DataAlt DataCon
con, [Var]
ex_tvs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var]
arg_ids, CoreExpr
rhs)])
where
([Var]
ex_tvs, [Var]
arg_ids) = [Unique] -> Type -> DataCon -> [Type] -> ([Var], [Var])
dataConRepInstPat [Unique]
us Type
mult DataCon
con [Type]
tys
[DataCon]
_ -> (Bool
False, [Alt Var]
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, [Alt Var]
all_alts)
| Bool
otherwise
= (Bool
False, [Alt Var]
all_alts)
combineIdenticalAlts :: [AltCon]
-> [CoreAlt]
-> (Bool,
[AltCon],
[CoreAlt])
combineIdenticalAlts :: [AltCon] -> [Alt Var] -> (Bool, [AltCon], [Alt Var])
combineIdenticalAlts [AltCon]
imposs_deflt_cons ((AltCon
con1,[Var]
bndrs1,CoreExpr
rhs1) : [Alt Var]
rest_alts)
| (Var -> Bool) -> [Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Var -> Bool
isDeadBinder [Var]
bndrs1
, Bool -> Bool
not ([Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Var]
elim_rest)
= (Bool
True, [AltCon]
imposs_deflt_cons', Alt Var
forall {a}. (AltCon, [a], CoreExpr)
deflt_alt Alt Var -> [Alt Var] -> [Alt Var]
forall a. a -> [a] -> [a]
: [Alt Var]
filtered_rest)
where
([Alt Var]
elim_rest, [Alt Var]
filtered_rest) = (Alt Var -> Bool) -> [Alt Var] -> ([Alt Var], [Alt Var])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Alt Var -> Bool
forall {t :: * -> *} {a}.
Foldable t =>
(a, t Var, CoreExpr) -> Bool
identical_to_alt1 [Alt Var]
rest_alts
deflt_alt :: (AltCon, [a], CoreExpr)
deflt_alt = (AltCon
DEFAULT, [], [Tickish Var] -> CoreExpr -> CoreExpr
mkTicks ([[Tickish Var]] -> [Tickish Var]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Tickish Var]]
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]
++ (Alt Var -> AltCon) -> [Alt Var] -> [AltCon]
forall a b. (a -> b) -> [a] -> [b]
map Alt Var -> AltCon
forall a b c. (a, b, c) -> a
fstOf3 [Alt Var]
elim_rest
elim_con1 :: [AltCon]
elim_con1 = case AltCon
con1 of
AltCon
DEFAULT -> []
AltCon
_ -> [AltCon
con1]
cheapEqTicked :: Expr b -> Expr b -> Bool
cheapEqTicked Expr b
e1 Expr b
e2 = (Tickish Var -> Bool) -> Expr b -> Expr b -> Bool
forall b. (Tickish Var -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishFloatable Expr b
e1 Expr b
e2
identical_to_alt1 :: (a, t Var, CoreExpr) -> Bool
identical_to_alt1 (a
_con,t Var
bndrs,CoreExpr
rhs)
= (Var -> Bool) -> t Var -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Var -> Bool
isDeadBinder t Var
bndrs Bool -> Bool -> Bool
&& CoreExpr
rhs CoreExpr -> CoreExpr -> Bool
forall {b}. Expr b -> Expr b -> Bool
`cheapEqTicked` CoreExpr
rhs1
tickss :: [[Tickish Var]]
tickss = (Alt Var -> [Tickish Var]) -> [Alt Var] -> [[Tickish Var]]
forall a b. (a -> b) -> [a] -> [b]
map ((Tickish Var -> Bool) -> CoreExpr -> [Tickish Var]
forall b. (Tickish Var -> Bool) -> Expr b -> [Tickish Var]
stripTicksT Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishFloatable (CoreExpr -> [Tickish Var])
-> (Alt Var -> CoreExpr) -> Alt Var -> [Tickish Var]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Alt Var -> CoreExpr
forall a b c. (a, b, c) -> c
thdOf3) [Alt Var]
elim_rest
combineIdenticalAlts [AltCon]
imposs_cons [Alt Var]
alts
= (Bool
False, [AltCon]
imposs_cons, [Alt Var]
alts)
scaleAltsBy :: Mult -> [CoreAlt] -> [CoreAlt]
scaleAltsBy :: Type -> [Alt Var] -> [Alt Var]
scaleAltsBy Type
w [Alt Var]
alts = (Alt Var -> Alt Var) -> [Alt Var] -> [Alt Var]
forall a b. (a -> b) -> [a] -> [b]
map Alt Var -> Alt Var
scaleAlt [Alt Var]
alts
where
scaleAlt :: CoreAlt -> CoreAlt
scaleAlt :: Alt Var -> Alt Var
scaleAlt (AltCon
con, [Var]
bndrs, CoreExpr
rhs) = (AltCon
con, (Var -> Var) -> [Var] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map Var -> Var
scaleBndr [Var]
bndrs, CoreExpr
rhs)
scaleBndr :: CoreBndr -> CoreBndr
scaleBndr :: Var -> Var
scaleBndr Var
b = Type -> Var -> Var
scaleVarBy Type
w Var
b
exprIsTrivial :: CoreExpr -> Bool
exprIsTrivial :: CoreExpr -> Bool
exprIsTrivial (Var Var
_) = Bool
True
exprIsTrivial (Type Type
_) = Bool
True
exprIsTrivial (Coercion CoercionR
_) = Bool
True
exprIsTrivial (Lit Literal
lit) = Literal -> Bool
litIsTrivial Literal
lit
exprIsTrivial (App CoreExpr
e CoreExpr
arg) = Bool -> Bool
not (CoreExpr -> Bool
isRuntimeArg CoreExpr
arg) Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Lam Var
b CoreExpr
e) = Bool -> Bool
not (Var -> Bool
isRuntimeVar Var
b) Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Tick Tickish Var
t CoreExpr
e) = Bool -> Bool
not (Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Var
t) Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Cast CoreExpr
e CoercionR
_) = CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial (Case CoreExpr
e Var
_ Type
_ []) = CoreExpr -> Bool
exprIsTrivial CoreExpr
e
exprIsTrivial CoreExpr
_ = Bool
False
getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Id
getIdFromTrivialExpr :: HasDebugCallStack => CoreExpr -> Var
getIdFromTrivialExpr CoreExpr
e
= Var -> Maybe Var -> Var
forall a. a -> Maybe a -> a
fromMaybe (String -> SDoc -> Var
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"getIdFromTrivialExpr" (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e))
(CoreExpr -> Maybe Var
getIdFromTrivialExpr_maybe CoreExpr
e)
getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Id
getIdFromTrivialExpr_maybe :: CoreExpr -> Maybe Var
getIdFromTrivialExpr_maybe CoreExpr
e
= CoreExpr -> Maybe Var
go CoreExpr
e
where
go :: CoreExpr -> Maybe Var
go (App CoreExpr
f CoreExpr
t) | Bool -> Bool
not (CoreExpr -> Bool
isRuntimeArg CoreExpr
t) = CoreExpr -> Maybe Var
go CoreExpr
f
go (Tick Tickish Var
t CoreExpr
e) | Bool -> Bool
not (Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Var
t) = CoreExpr -> Maybe Var
go CoreExpr
e
go (Cast CoreExpr
e CoercionR
_) = CoreExpr -> Maybe Var
go CoreExpr
e
go (Lam Var
b CoreExpr
e) | Bool -> Bool
not (Var -> Bool
isRuntimeVar Var
b) = CoreExpr -> Maybe Var
go CoreExpr
e
go (Case CoreExpr
e Var
_ Type
_ []) = CoreExpr -> Maybe Var
go CoreExpr
e
go (Var Var
v) = Var -> Maybe Var
forall a. a -> Maybe a
Just Var
v
go CoreExpr
_ = Maybe Var
forall a. Maybe a
Nothing
exprIsDeadEnd :: CoreExpr -> Bool
exprIsDeadEnd :: CoreExpr -> Bool
exprIsDeadEnd CoreExpr
e
| Type -> Bool
isEmptyTy (CoreExpr -> Type
exprType CoreExpr
e)
= Bool
True
| Bool
otherwise
= Int -> CoreExpr -> Bool
go Int
0 CoreExpr
e
where
go :: Int -> CoreExpr -> Bool
go Int
n (Var Var
v) = Var -> Bool
isDeadEndId Var
v Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Var -> Int
idArity Var
v
go Int
n (App CoreExpr
e 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
+Int
1) CoreExpr
e
go Int
n (Tick Tickish Var
_ CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Cast CoreExpr
e CoercionR
_) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Let Bind Var
_ CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Lam Var
v CoreExpr
e) | Var -> Bool
isTyVar Var
v = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
_ (Case CoreExpr
_ Var
_ Type
_ [Alt Var]
alts) = [Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Var]
alts
go Int
_ CoreExpr
_ = Bool
False
exprIsDupable :: Platform -> CoreExpr -> Bool
exprIsDupable :: Platform -> CoreExpr -> Bool
exprIsDupable Platform
platform 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 Int
n (Type {}) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
go Int
n (Coercion {}) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n
go Int
n (Var {}) = Int -> Maybe Int
decrement Int
n
go Int
n (Tick Tickish Var
_ CoreExpr
e) = Int -> CoreExpr -> Maybe Int
go Int
n CoreExpr
e
go Int
n (Cast CoreExpr
e CoercionR
_) = Int -> CoreExpr -> Maybe Int
go Int
n CoreExpr
e
go Int
n (App CoreExpr
f CoreExpr
a) | Just Int
n' <- Int -> CoreExpr -> Maybe Int
go Int
n CoreExpr
a = Int -> CoreExpr -> Maybe Int
go Int
n' CoreExpr
f
go Int
n (Lit Literal
lit) | Platform -> Literal -> Bool
litIsDupable Platform
platform Literal
lit = Int -> Maybe Int
decrement Int
n
go Int
_ CoreExpr
_ = Maybe Int
forall a. Maybe a
Nothing
decrement :: Int -> Maybe Int
decrement :: Int -> Maybe Int
decrement Int
0 = Maybe Int
forall a. Maybe a
Nothing
decrement Int
n = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
dupAppSize :: Int
dupAppSize :: Int
dupAppSize = Int
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 CheapAppFun
ok_app CoreExpr
e
= CoreExpr -> Bool
ok CoreExpr
e
where
ok :: CoreExpr -> Bool
ok CoreExpr
e = Int -> CoreExpr -> Bool
go Int
0 CoreExpr
e
go :: Int -> CoreExpr -> Bool
go Int
n (Var Var
v) = CheapAppFun
ok_app Var
v Int
n
go Int
_ (Lit {}) = Bool
True
go Int
_ (Type {}) = Bool
True
go Int
_ (Coercion {}) = Bool
True
go Int
n (Cast CoreExpr
e CoercionR
_) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Case CoreExpr
scrut Var
_ Type
_ [Alt Var]
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 | (AltCon
_,[Var]
_,CoreExpr
rhs) <- [Alt Var]
alts ]
go Int
n (Tick Tickish Var
t CoreExpr
e) | Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Var
t = Bool
False
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Lam Var
x CoreExpr
e) | Var -> Bool
isRuntimeVar Var
x = Int
nInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0 Bool -> Bool -> Bool
|| Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (App CoreExpr
f CoreExpr
e) | CoreExpr -> Bool
isRuntimeArg CoreExpr
e = Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) CoreExpr
f Bool -> Bool -> Bool
&& CoreExpr -> Bool
ok CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
f
go Int
n (Let (NonRec Var
_ CoreExpr
r) CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e Bool -> Bool -> Bool
&& CoreExpr -> Bool
ok CoreExpr
r
go Int
n (Let (Rec [(Var, CoreExpr)]
prs) CoreExpr
e) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e Bool -> Bool -> Bool
&& ((Var, CoreExpr) -> Bool) -> [(Var, CoreExpr)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CoreExpr -> Bool
ok (CoreExpr -> Bool)
-> ((Var, CoreExpr) -> CoreExpr) -> (Var, CoreExpr) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Var, CoreExpr) -> CoreExpr
forall a b. (a, b) -> b
snd) [(Var, CoreExpr)]
prs
exprIsExpandable :: CoreExpr -> Bool
exprIsExpandable :: CoreExpr -> Bool
exprIsExpandable CoreExpr
e
= CoreExpr -> Bool
ok CoreExpr
e
where
ok :: CoreExpr -> Bool
ok CoreExpr
e = Int -> CoreExpr -> Bool
go Int
0 CoreExpr
e
go :: Int -> CoreExpr -> Bool
go Int
n (Var Var
v) = CheapAppFun
isExpandableApp Var
v Int
n
go Int
_ (Lit {}) = Bool
True
go Int
_ (Type {}) = Bool
True
go Int
_ (Coercion {}) = Bool
True
go Int
n (Cast CoreExpr
e CoercionR
_) = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Tick Tickish Var
t CoreExpr
e) | Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Var
t = Bool
False
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (Lam Var
x CoreExpr
e) | Var -> Bool
isRuntimeVar Var
x = Int
nInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0 Bool -> Bool -> Bool
|| Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
e
go Int
n (App CoreExpr
f CoreExpr
e) | CoreExpr -> Bool
isRuntimeArg CoreExpr
e = Int -> CoreExpr -> Bool
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) CoreExpr
f Bool -> Bool -> Bool
&& CoreExpr -> Bool
ok CoreExpr
e
| Bool
otherwise = Int -> CoreExpr -> Bool
go Int
n CoreExpr
f
go Int
_ (Case {}) = Bool
False
go Int
_ (Let {}) = Bool
False
type CheapAppFun = Id -> Arity -> Bool
isWorkFreeApp :: CheapAppFun
isWorkFreeApp :: CheapAppFun
isWorkFreeApp Var
fn Int
n_val_args
| Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
= Bool
True
| Int
n_val_args Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Var -> Int
idArity Var
fn
= Bool
True
| Bool
otherwise
= case Var -> IdDetails
idDetails Var
fn of
DataConWorkId {} -> Bool
True
IdDetails
_ -> Bool
False
isCheapApp :: CheapAppFun
isCheapApp :: CheapAppFun
isCheapApp Var
fn Int
n_val_args
| CheapAppFun
isWorkFreeApp Var
fn Int
n_val_args = Bool
True
| Var -> Bool
isDeadEndId Var
fn = Bool
True
| Bool
otherwise
= case Var -> IdDetails
idDetails Var
fn of
DataConWorkId {} -> Bool
True
RecSelId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
ClassOpId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
PrimOpId PrimOp
op -> PrimOp -> Bool
primOpIsCheap PrimOp
op
IdDetails
_ -> Bool
False
isExpandableApp :: CheapAppFun
isExpandableApp :: CheapAppFun
isExpandableApp Var
fn Int
n_val_args
| CheapAppFun
isWorkFreeApp Var
fn Int
n_val_args = Bool
True
| Bool
otherwise
= case Var -> IdDetails
idDetails Var
fn of
RecSelId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
ClassOpId {} -> Int
n_val_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
PrimOpId {} -> Bool
False
IdDetails
_ | Var -> Bool
isDeadEndId Var
fn -> Bool
False
| Var -> Bool
isConLikeId Var
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 (Var -> Type
idType Var
fn)
all_pred_args :: a -> Type -> Bool
all_pred_args a
n_val_args Type
ty
| a
n_val_args a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
= Bool
True
| Just (TyCoBinder
bndr, Type
ty) <- Type -> Maybe (TyCoBinder, Type)
splitPiTy_maybe Type
ty
= case TyCoBinder
bndr of
Named {} -> a -> Type -> Bool
all_pred_args a
n_val_args Type
ty
Anon AnonArgFlag
InvisArg Scaled Type
_ -> a -> Type -> Bool
all_pred_args (a
n_val_argsa -> a -> a
forall a. Num a => a -> a -> a
-a
1) Type
ty
Anon AnonArgFlag
VisArg Scaled Type
_ -> Bool
False
| 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 PrimOp -> Bool
_ (Lit Literal
_) = Bool
True
expr_ok PrimOp -> Bool
_ (Type Type
_) = Bool
True
expr_ok PrimOp -> Bool
_ (Coercion CoercionR
_) = Bool
True
expr_ok PrimOp -> Bool
primop_ok (Var Var
v) = (PrimOp -> Bool) -> Var -> [CoreExpr] -> Bool
app_ok PrimOp -> Bool
primop_ok Var
v []
expr_ok PrimOp -> Bool
primop_ok (Cast CoreExpr
e CoercionR
_) = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
e
expr_ok PrimOp -> Bool
primop_ok (Lam Var
b CoreExpr
e)
| Var -> Bool
isTyVar Var
b = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
e
| Bool
otherwise = Bool
True
expr_ok PrimOp -> Bool
primop_ok (Tick Tickish Var
tickish CoreExpr
e)
| Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Var
tickish = Bool
False
| Bool
otherwise = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
e
expr_ok PrimOp -> Bool
_ (Let {}) = Bool
False
expr_ok PrimOp -> Bool
primop_ok (Case CoreExpr
scrut Var
bndr Type
_ [Alt Var]
alts)
=
(PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
scrut
Bool -> Bool -> Bool
&& HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Var -> Type
idType Var
bndr)
Bool -> Bool -> Bool
&& (Alt Var -> Bool) -> [Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\(AltCon
_,[Var]
_,CoreExpr
rhs) -> (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
rhs) [Alt Var]
alts
Bool -> Bool -> Bool
&& [Alt Var] -> Bool
forall b. [Alt b] -> Bool
altsAreExhaustive [Alt Var]
alts
expr_ok PrimOp -> Bool
primop_ok CoreExpr
other_expr
| (CoreExpr
expr, [CoreExpr]
args) <- CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
other_expr
= case (Tickish Var -> Bool) -> CoreExpr -> CoreExpr
forall b. (Tickish Var -> Bool) -> Expr b -> Expr b
stripTicksTopE (Bool -> Bool
not (Bool -> Bool) -> (Tickish Var -> Bool) -> Tickish Var -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishCounts) CoreExpr
expr of
Var Var
f -> (PrimOp -> Bool) -> Var -> [CoreExpr] -> Bool
app_ok PrimOp -> Bool
primop_ok Var
f [CoreExpr]
args
Lit Literal
lit -> ASSERT( lit == rubbishLit ) True
CoreExpr
_ -> Bool
False
app_ok :: (PrimOp -> Bool) -> Id -> [CoreExpr] -> Bool
app_ok :: (PrimOp -> Bool) -> Var -> [CoreExpr] -> Bool
app_ok PrimOp -> Bool
primop_ok Var
fun [CoreExpr]
args
= case Var -> IdDetails
idDetails Var
fun of
DFunId Bool
new_type -> Bool -> Bool
not Bool
new_type
DataConWorkId {} -> Bool
True
PrimOpId PrimOp
op
| PrimOp -> Bool
isDivOp PrimOp
op
, [CoreExpr
arg1, 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
| PrimOp
KeepAliveOp <- 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)
IdDetails
_other -> HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Var -> Type
idType Var
fun)
Bool -> Bool -> Bool
|| Var -> Int
idArity Var
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
([TyCoBinder]
arg_tys, Type
_) = Type -> ([TyCoBinder], Type)
splitPiTys (Var -> Type
idType Var
fun)
primop_arg_ok :: TyBinder -> CoreExpr -> Bool
primop_arg_ok :: TyCoBinder -> CoreExpr -> Bool
primop_arg_ok (Named TyCoVarBinder
_) CoreExpr
_ = Bool
True
primop_arg_ok (Anon AnonArgFlag
_ Scaled Type
ty) CoreExpr
arg
| HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
ty) = (PrimOp -> Bool) -> CoreExpr -> Bool
expr_ok PrimOp -> Bool
primop_ok CoreExpr
arg
| Bool
otherwise = Bool
True
altsAreExhaustive :: [Alt b] -> Bool
altsAreExhaustive :: forall b. [Alt b] -> Bool
altsAreExhaustive []
= Bool
False
altsAreExhaustive ((AltCon
con1,[b]
_,Expr b
_) : [Alt b]
alts)
= case AltCon
con1 of
AltCon
DEFAULT -> Bool
True
LitAlt {} -> Bool
False
DataAlt 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
- Int
1)
isDivOp :: PrimOp -> Bool
isDivOp :: PrimOp -> Bool
isDivOp PrimOp
IntQuotOp = Bool
True
isDivOp PrimOp
IntRemOp = Bool
True
isDivOp PrimOp
WordQuotOp = Bool
True
isDivOp PrimOp
WordRemOp = Bool
True
isDivOp PrimOp
FloatDivOp = Bool
True
isDivOp PrimOp
DoubleDivOp = Bool
True
isDivOp PrimOp
_ = Bool
False
exprIsHNF :: CoreExpr -> Bool
exprIsHNF :: CoreExpr -> Bool
exprIsHNF = (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike Var -> Bool
isDataConWorkId Unfolding -> Bool
isEvaldUnfolding
exprIsConLike :: CoreExpr -> Bool
exprIsConLike :: CoreExpr -> Bool
exprIsConLike = (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike Var -> Bool
isConLikeId Unfolding -> Bool
isConLikeUnfolding
exprIsHNFlike :: (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike :: (Var -> Bool) -> (Unfolding -> Bool) -> CoreExpr -> Bool
exprIsHNFlike Var -> Bool
is_con Unfolding -> Bool
is_con_unf = CoreExpr -> Bool
is_hnf_like
where
is_hnf_like :: CoreExpr -> Bool
is_hnf_like (Var Var
v)
= CheapAppFun
id_app_is_value Var
v Int
0
Bool -> Bool -> Bool
|| Unfolding -> Bool
is_con_unf (Var -> Unfolding
idUnfolding Var
v)
is_hnf_like (Lit Literal
_) = Bool
True
is_hnf_like (Type Type
_) = Bool
True
is_hnf_like (Coercion CoercionR
_) = Bool
True
is_hnf_like (Lam Var
b CoreExpr
e) = Var -> Bool
isRuntimeVar Var
b Bool -> Bool -> Bool
|| CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (Tick Tickish Var
tickish CoreExpr
e) = Bool -> Bool
not (Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Var
tickish)
Bool -> Bool -> Bool
&& CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (Cast CoreExpr
e CoercionR
_) = CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (App CoreExpr
e CoreExpr
a)
| CoreExpr -> Bool
forall b. Expr b -> Bool
isValArg CoreExpr
a = CoreExpr -> Int -> Bool
app_is_value CoreExpr
e Int
1
| Bool
otherwise = CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like (Let Bind Var
_ CoreExpr
e) = CoreExpr -> Bool
is_hnf_like CoreExpr
e
is_hnf_like CoreExpr
_ = Bool
False
app_is_value :: CoreExpr -> Int -> Bool
app_is_value :: CoreExpr -> Int -> Bool
app_is_value (Var Var
f) Int
nva = CheapAppFun
id_app_is_value Var
f Int
nva
app_is_value (Tick Tickish Var
_ CoreExpr
f) Int
nva = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f Int
nva
app_is_value (Cast CoreExpr
f CoercionR
_) Int
nva = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f Int
nva
app_is_value (App CoreExpr
f CoreExpr
a) 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
+ Int
1)
| Bool
otherwise = CoreExpr -> Int -> Bool
app_is_value CoreExpr
f Int
nva
app_is_value CoreExpr
_ Int
_ = Bool
False
id_app_is_value :: CheapAppFun
id_app_is_value Var
id Int
n_val_args
= Var -> Bool
is_con Var
id
Bool -> Bool -> Bool
|| Var -> Int
idArity Var
id Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n_val_args
Bool -> Bool -> Bool
|| Var
id Var -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
absentErrorIdKey
exprIsTopLevelBindable :: CoreExpr -> Type -> Bool
exprIsTopLevelBindable :: CoreExpr -> Type -> Bool
exprIsTopLevelBindable CoreExpr
expr Type
ty
= Bool -> Bool
not (Type -> Bool
mightBeUnliftedType 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 ByteString
bs)) = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
bs
exprIsTickedString_maybe (Tick Tickish Var
t CoreExpr
e)
| Tickish Var -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Var
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 CoreExpr
_ = Maybe ByteString
forall a. Maybe a
Nothing
dataConRepInstPat :: [Unique] -> Mult -> DataCon -> [Type] -> ([TyCoVar], [Id])
dataConRepFSInstPat :: [FastString] -> [Unique] -> Mult -> DataCon -> [Type] -> ([TyCoVar], [Id])
dataConRepInstPat :: [Unique] -> Type -> DataCon -> [Type] -> ([Var], [Var])
dataConRepInstPat = [FastString]
-> [Unique] -> Type -> DataCon -> [Type] -> ([Var], [Var])
dataConInstPat (FastString -> [FastString]
forall a. a -> [a]
repeat ((String -> FastString
fsLit String
"ipv")))
dataConRepFSInstPat :: [FastString]
-> [Unique] -> Type -> DataCon -> [Type] -> ([Var], [Var])
dataConRepFSInstPat = [FastString]
-> [Unique] -> Type -> DataCon -> [Type] -> ([Var], [Var])
dataConInstPat
dataConInstPat :: [FastString]
-> [Unique]
-> Mult
-> DataCon
-> [Type]
-> ([TyCoVar], [Id])
dataConInstPat :: [FastString]
-> [Unique] -> Type -> DataCon -> [Type] -> ([Var], [Var])
dataConInstPat [FastString]
fss [Unique]
uniqs Type
mult DataCon
con [Type]
inst_tys
= ASSERT( univ_tvs `equalLength` inst_tys )
([Var]
ex_bndrs, [Var]
arg_ids)
where
univ_tvs :: [Var]
univ_tvs = DataCon -> [Var]
dataConUnivTyVars DataCon
con
ex_tvs :: [Var]
ex_tvs = DataCon -> [Var]
dataConExTyCoVars DataCon
con
arg_tys :: [Scaled Type]
arg_tys = DataCon -> [Scaled Type]
dataConRepArgTys DataCon
con
arg_strs :: [StrictnessMark]
arg_strs = DataCon -> [StrictnessMark]
dataConRepStrictness DataCon
con
n_ex :: Int
n_ex = [Var] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Var]
ex_tvs
([Unique]
ex_uniqs, [Unique]
id_uniqs) = Int -> [Unique] -> ([Unique], [Unique])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n_ex [Unique]
uniqs
([FastString]
ex_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 = [Var] -> [Type] -> TCvSubst
HasDebugCallStack => [Var] -> [Type] -> TCvSubst
zipTvSubst [Var]
univ_tvs [Type]
inst_tys
(TCvSubst
full_subst, [Var]
ex_bndrs) = (TCvSubst -> (Var, FastString, Unique) -> (TCvSubst, Var))
-> TCvSubst -> [(Var, FastString, Unique)] -> (TCvSubst, [Var])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumL TCvSubst -> (Var, FastString, Unique) -> (TCvSubst, Var)
mk_ex_var TCvSubst
univ_subst
([Var] -> [FastString] -> [Unique] -> [(Var, FastString, Unique)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Var]
ex_tvs [FastString]
ex_fss [Unique]
ex_uniqs)
mk_ex_var :: TCvSubst -> (TyCoVar, FastString, Unique) -> (TCvSubst, TyCoVar)
mk_ex_var :: TCvSubst -> (Var, FastString, Unique) -> (TCvSubst, Var)
mk_ex_var TCvSubst
subst (Var
tv, FastString
fs, Unique
uniq) = (TCvSubst -> Var -> Var -> TCvSubst
Type.extendTCvSubstWithClone TCvSubst
subst Var
tv
Var
new_tv
, Var
new_tv)
where
new_tv :: Var
new_tv | Var -> Bool
isTyVar Var
tv
= Name -> Type -> Var
mkTyVar (Unique -> FastString -> Name
mkSysTvName Unique
uniq FastString
fs) Type
kind
| Bool
otherwise
= Name -> Type -> Var
mkCoVar (Unique -> FastString -> Name
mkSystemVarName Unique
uniq FastString
fs) Type
kind
kind :: Type
kind = TCvSubst -> Type -> Type
Type.substTyUnchecked TCvSubst
subst (Var -> Type
varType Var
tv)
arg_ids :: [Var]
arg_ids = (Unique -> FastString -> Scaled Type -> StrictnessMark -> Var)
-> [Unique]
-> [FastString]
-> [Scaled Type]
-> [StrictnessMark]
-> [Var]
forall a b c d e.
(a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
zipWith4 Unique -> FastString -> Scaled Type -> StrictnessMark -> Var
mk_id_var [Unique]
id_uniqs [FastString]
id_fss [Scaled Type]
arg_tys [StrictnessMark]
arg_strs
mk_id_var :: Unique -> FastString -> Scaled Type -> StrictnessMark -> Var
mk_id_var Unique
uniq FastString
fs (Scaled Type
m Type
ty) StrictnessMark
str
= StrictnessMark -> Var -> Var
setCaseBndrEvald StrictnessMark
str (Var -> Var) -> Var -> Var
forall a b. (a -> b) -> a -> b
$
Name -> Type -> Type -> Var
mkLocalIdOrCoVar Name
name (Type
mult Type -> Type -> Type
`mkMultMul` Type
m) (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 :: forall {b}. Expr b -> Expr b -> Bool
cheapEqExpr = (Tickish Var -> Bool) -> Expr b -> Expr b -> Bool
forall b. (Tickish Var -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' (Bool -> Tickish Var -> Bool
forall a b. a -> b -> a
const Bool
False)
cheapEqExpr' :: (Tickish Id -> Bool) -> Expr b -> Expr b -> Bool
{-# INLINE cheapEqExpr' #-}
cheapEqExpr' :: forall b. (Tickish Var -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' Tickish Var -> Bool
ignoreTick Expr b
e1 Expr b
e2
= Expr b -> Expr b -> Bool
forall {b} {b}. Expr b -> Expr b -> Bool
go Expr b
e1 Expr b
e2
where
go :: Expr b -> Expr b -> Bool
go (Var Var
v1) (Var Var
v2) = Var
v1 Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
v2
go (Lit Literal
lit1) (Lit Literal
lit2) = Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2
go (Type Type
t1) (Type Type
t2) = Type
t1 Type -> Type -> Bool
`eqType` Type
t2
go (Coercion CoercionR
c1) (Coercion CoercionR
c2) = CoercionR
c1 CoercionR -> CoercionR -> Bool
`eqCoercion` CoercionR
c2
go (App Expr b
f1 Expr b
a1) (App Expr b
f2 Expr b
a2) = Expr b
f1 Expr b -> Expr b -> Bool
`go` Expr b
f2 Bool -> Bool -> Bool
&& Expr b
a1 Expr b -> Expr b -> Bool
`go` Expr b
a2
go (Cast Expr b
e1 CoercionR
t1) (Cast Expr b
e2 CoercionR
t2) = Expr b
e1 Expr b -> Expr b -> Bool
`go` Expr b
e2 Bool -> Bool -> Bool
&& CoercionR
t1 CoercionR -> CoercionR -> Bool
`eqCoercion` CoercionR
t2
go (Tick Tickish Var
t1 Expr b
e1) Expr b
e2 | Tickish Var -> Bool
ignoreTick Tickish Var
t1 = Expr b -> Expr b -> Bool
go Expr b
e1 Expr b
e2
go Expr b
e1 (Tick Tickish Var
t2 Expr b
e2) | Tickish Var -> Bool
ignoreTick Tickish Var
t2 = Expr b -> Expr b -> Bool
go Expr b
e1 Expr b
e2
go (Tick Tickish Var
t1 Expr b
e1) (Tick Tickish Var
t2 Expr b
e2) = Tickish Var
t1 Tickish Var -> Tickish Var -> Bool
forall a. Eq a => a -> a -> Bool
== Tickish Var
t2 Bool -> Bool -> Bool
&& Expr b
e1 Expr b -> Expr b -> Bool
`go` Expr b
e2
go Expr b
_ Expr b
_ = Bool
False
eqExpr :: InScopeSet -> CoreExpr -> CoreExpr -> Bool
eqExpr :: InScopeSet -> CoreExpr -> CoreExpr -> Bool
eqExpr InScopeSet
in_scope CoreExpr
e1 CoreExpr
e2
= RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (InScopeSet -> RnEnv2
mkRnEnv2 InScopeSet
in_scope) CoreExpr
e1 CoreExpr
e2
where
go :: RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env (Var Var
v1) (Var Var
v2)
| RnEnv2 -> Var -> Var
rnOccL RnEnv2
env Var
v1 Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== RnEnv2 -> Var -> Var
rnOccR RnEnv2
env Var
v2
= Bool
True
go RnEnv2
_ (Lit Literal
lit1) (Lit Literal
lit2) = Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2
go RnEnv2
env (Type Type
t1) (Type Type
t2) = RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2
go RnEnv2
env (Coercion CoercionR
co1) (Coercion CoercionR
co2) = RnEnv2 -> CoercionR -> CoercionR -> Bool
eqCoercionX RnEnv2
env CoercionR
co1 CoercionR
co2
go RnEnv2
env (Cast CoreExpr
e1 CoercionR
co1) (Cast CoreExpr
e2 CoercionR
co2) = RnEnv2 -> CoercionR -> CoercionR -> Bool
eqCoercionX RnEnv2
env CoercionR
co1 CoercionR
co2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
e1 CoreExpr
e2
go RnEnv2
env (App CoreExpr
f1 CoreExpr
a1) (App CoreExpr
f2 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 RnEnv2
env (Tick Tickish Var
n1 CoreExpr
e1) (Tick Tickish Var
n2 CoreExpr
e2) = RnEnv2 -> Tickish Var -> Tickish Var -> Bool
eqTickish RnEnv2
env Tickish Var
n1 Tickish Var
n2 Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
e1 CoreExpr
e2
go RnEnv2
env (Lam Var
b1 CoreExpr
e1) (Lam Var
b2 CoreExpr
e2)
= RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env (Var -> Type
varType Var
b1) (Var -> Type
varType Var
b2)
Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
b1 Var
b2) CoreExpr
e1 CoreExpr
e2
go RnEnv2
env (Let (NonRec Var
v1 CoreExpr
r1) CoreExpr
e1) (Let (NonRec Var
v2 CoreExpr
r2) CoreExpr
e2)
= RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go RnEnv2
env CoreExpr
r1 CoreExpr
r2
Bool -> Bool -> Bool
&& RnEnv2 -> CoreExpr -> CoreExpr -> Bool
go (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
v1 Var
v2) CoreExpr
e1 CoreExpr
e2
go RnEnv2
env (Let (Rec [(Var, CoreExpr)]
ps1) CoreExpr
e1) (Let (Rec [(Var, CoreExpr)]
ps2) CoreExpr
e2)
= [(Var, CoreExpr)] -> [(Var, CoreExpr)] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [(Var, CoreExpr)]
ps1 [(Var, 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
([Var]
bs1,[CoreExpr]
rs1) = [(Var, CoreExpr)] -> ([Var], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Var, CoreExpr)]
ps1
([Var]
bs2,[CoreExpr]
rs2) = [(Var, CoreExpr)] -> ([Var], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Var, CoreExpr)]
ps2
env' :: RnEnv2
env' = RnEnv2 -> [Var] -> [Var] -> RnEnv2
rnBndrs2 RnEnv2
env [Var]
bs1 [Var]
bs2
go RnEnv2
env (Case CoreExpr
e1 Var
b1 Type
t1 [Alt Var]
a1) (Case CoreExpr
e2 Var
b2 Type
t2 [Alt Var]
a2)
| [Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Var]
a1
= [Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Var]
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
&& (Alt Var -> Alt Var -> Bool) -> [Alt Var] -> [Alt Var] -> Bool
forall a b. (a -> b -> Bool) -> [a] -> [b] -> Bool
all2 (RnEnv2 -> Alt Var -> Alt Var -> Bool
go_alt (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
b1 Var
b2)) [Alt Var]
a1 [Alt Var]
a2
go RnEnv2
_ CoreExpr
_ CoreExpr
_ = Bool
False
go_alt :: RnEnv2 -> Alt Var -> Alt Var -> Bool
go_alt RnEnv2
env (AltCon
c1, [Var]
bs1, CoreExpr
e1) (AltCon
c2, [Var]
bs2, 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 -> [Var] -> [Var] -> RnEnv2
rnBndrs2 RnEnv2
env [Var]
bs1 [Var]
bs2) CoreExpr
e1 CoreExpr
e2
eqTickish :: RnEnv2 -> Tickish Id -> Tickish Id -> Bool
eqTickish :: RnEnv2 -> Tickish Var -> Tickish Var -> Bool
eqTickish RnEnv2
env (Breakpoint Int
lid [Var]
lids) (Breakpoint Int
rid [Var]
rids)
= Int
lid Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rid Bool -> Bool -> Bool
&& (Var -> Var) -> [Var] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (RnEnv2 -> Var -> Var
rnOccL RnEnv2
env) [Var]
lids [Var] -> [Var] -> Bool
forall a. Eq a => a -> a -> Bool
== (Var -> Var) -> [Var] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (RnEnv2 -> Var -> Var
rnOccR RnEnv2
env) [Var]
rids
eqTickish RnEnv2
_ Tickish Var
l Tickish Var
r = Tickish Var
l Tickish Var -> Tickish Var -> Bool
forall a. Eq a => a -> a -> Bool
== Tickish Var
r
diffExpr :: Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr :: Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
_ RnEnv2
env (Var Var
v1) (Var Var
v2) | RnEnv2 -> Var -> Var
rnOccL RnEnv2
env Var
v1 Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== RnEnv2 -> Var -> Var
rnOccR RnEnv2
env Var
v2 = []
diffExpr Bool
_ RnEnv2
_ (Lit Literal
lit1) (Lit Literal
lit2) | Literal
lit1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
lit2 = []
diffExpr Bool
_ RnEnv2
env (Type Type
t1) (Type Type
t2) | RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env Type
t1 Type
t2 = []
diffExpr Bool
_ RnEnv2
env (Coercion CoercionR
co1) (Coercion CoercionR
co2)
| RnEnv2 -> CoercionR -> CoercionR -> Bool
eqCoercionX RnEnv2
env CoercionR
co1 CoercionR
co2 = []
diffExpr Bool
top RnEnv2
env (Cast CoreExpr
e1 CoercionR
co1) (Cast CoreExpr
e2 CoercionR
co2)
| RnEnv2 -> CoercionR -> CoercionR -> Bool
eqCoercionX RnEnv2
env CoercionR
co1 CoercionR
co2 = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr Bool
top RnEnv2
env (Tick Tickish Var
n1 CoreExpr
e1) CoreExpr
e2
| Bool -> Bool
not (Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Var
n1) = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr Bool
top RnEnv2
env CoreExpr
e1 (Tick Tickish Var
n2 CoreExpr
e2)
| Bool -> Bool
not (Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishIsCode Tickish Var
n2) = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr Bool
top RnEnv2
env (Tick Tickish Var
n1 CoreExpr
e1) (Tick Tickish Var
n2 CoreExpr
e2)
| RnEnv2 -> Tickish Var -> Tickish Var -> Bool
eqTickish RnEnv2
env Tickish Var
n1 Tickish Var
n2 = Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
e1 CoreExpr
e2
diffExpr Bool
_ RnEnv2
_ (App (App (Var Var
absent) CoreExpr
_) CoreExpr
_)
(App (App (Var Var
absent2) CoreExpr
_) CoreExpr
_)
| Var -> Bool
isDeadEndId Var
absent Bool -> Bool -> Bool
&& Var -> Bool
isDeadEndId Var
absent2 = []
diffExpr Bool
top RnEnv2
env (App CoreExpr
f1 CoreExpr
a1) (App CoreExpr
f2 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 Bool
top RnEnv2
env (Lam Var
b1 CoreExpr
e1) (Lam Var
b2 CoreExpr
e2)
| RnEnv2 -> Type -> Type -> Bool
eqTypeX RnEnv2
env (Var -> Type
varType Var
b1) (Var -> Type
varType Var
b2)
= Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
b1 Var
b2) CoreExpr
e1 CoreExpr
e2
diffExpr Bool
top RnEnv2
env (Let Bind Var
bs1 CoreExpr
e1) (Let Bind Var
bs2 CoreExpr
e2)
= let ([SDoc]
ds, RnEnv2
env') = Bool
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds Bool
top RnEnv2
env ([Bind Var] -> [(Var, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds [Bind Var
bs1]) ([Bind Var] -> [(Var, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds [Bind Var
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 Bool
top RnEnv2
env (Case CoreExpr
e1 Var
b1 Type
t1 [Alt Var]
a1) (Case CoreExpr
e2 Var
b2 Type
t2 [Alt Var]
a2)
| [Alt Var] -> [Alt Var] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [Alt Var]
a1 [Alt Var]
a2 Bool -> Bool -> Bool
&& Bool -> Bool
not ([Alt Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Alt Var]
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 ((Alt Var -> Alt Var -> [SDoc])
-> [Alt Var] -> [Alt Var] -> [[SDoc]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Alt Var -> Alt Var -> [SDoc]
forall {a}.
(Eq a, Outputable a) =>
(a, [Var], CoreExpr) -> (a, [Var], CoreExpr) -> [SDoc]
diffAlt [Alt Var]
a1 [Alt Var]
a2)
where env' :: RnEnv2
env' = RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
b1 Var
b2
diffAlt :: (a, [Var], CoreExpr) -> (a, [Var], CoreExpr) -> [SDoc]
diffAlt (a
c1, [Var]
bs1, CoreExpr
e1) (a
c2, [Var]
bs2, CoreExpr
e2)
| a
c1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
c2 = [String -> SDoc
text String
"alt-cons " SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
c1 SDoc -> SDoc -> SDoc
<> String -> SDoc
text String
" /= " 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 -> [Var] -> [Var] -> RnEnv2
rnBndrs2 RnEnv2
env' [Var]
bs1 [Var]
bs2) CoreExpr
e1 CoreExpr
e2
diffExpr Bool
_ RnEnv2
_ CoreExpr
e1 CoreExpr
e2
= [[SDoc] -> SDoc
fsep [CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e1, String -> SDoc
text String
"/=", CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e2]]
diffBinds :: Bool -> RnEnv2 -> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds :: Bool
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
diffBinds Bool
top RnEnv2
env [(Var, CoreExpr)]
binds1 = Int
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
go ([(Var, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Var, CoreExpr)]
binds1) RnEnv2
env [(Var, CoreExpr)]
binds1
where go :: Int
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
go Int
_ RnEnv2
env [] []
= ([], RnEnv2
env)
go Int
fuel RnEnv2
env [(Var, CoreExpr)]
binds1 [(Var, CoreExpr)]
binds2
| [(Var, CoreExpr)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Var, CoreExpr)]
binds1 Bool -> Bool -> Bool
|| [(Var, CoreExpr)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Var, CoreExpr)]
binds2
= (RnEnv2 -> [(Var, CoreExpr)] -> [(Var, CoreExpr)] -> [SDoc]
warn RnEnv2
env [(Var, CoreExpr)]
binds1 [(Var, CoreExpr)]
binds2, RnEnv2
env)
| Int
fuel Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
= if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ RnEnv2
env RnEnv2 -> Var -> Bool
`inRnEnvL` (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst ([(Var, CoreExpr)] -> (Var, CoreExpr)
forall a. [a] -> a
head [(Var, CoreExpr)]
binds1)
then let env' :: RnEnv2
env' = ([Var] -> [Var] -> RnEnv2) -> ([Var], [Var]) -> RnEnv2
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (RnEnv2 -> [Var] -> [Var] -> RnEnv2
rnBndrs2 RnEnv2
env) (([Var], [Var]) -> RnEnv2) -> ([Var], [Var]) -> RnEnv2
forall a b. (a -> b) -> a -> b
$ [(Var, Var)] -> ([Var], [Var])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Var, Var)] -> ([Var], [Var])) -> [(Var, Var)] -> ([Var], [Var])
forall a b. (a -> b) -> a -> b
$
[Var] -> [Var] -> [(Var, Var)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([Var] -> [Var]
forall a. Ord a => [a] -> [a]
sort ([Var] -> [Var]) -> [Var] -> [Var]
forall a b. (a -> b) -> a -> b
$ ((Var, CoreExpr) -> Var) -> [(Var, CoreExpr)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst [(Var, CoreExpr)]
binds1) ([Var] -> [Var]
forall a. Ord a => [a] -> [a]
sort ([Var] -> [Var]) -> [Var] -> [Var]
forall a b. (a -> b) -> a -> b
$ ((Var, CoreExpr) -> Var) -> [(Var, CoreExpr)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst [(Var, CoreExpr)]
binds2)
in Int
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
go ([(Var, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Var, CoreExpr)]
binds1) RnEnv2
env' [(Var, CoreExpr)]
binds1 [(Var, CoreExpr)]
binds2
else (RnEnv2 -> [(Var, CoreExpr)] -> [(Var, CoreExpr)] -> [SDoc]
warn RnEnv2
env [(Var, CoreExpr)]
binds1 [(Var, CoreExpr)]
binds2, RnEnv2
env)
go Int
fuel RnEnv2
env ((Var
bndr1,CoreExpr
expr1):[(Var, CoreExpr)]
binds1) [(Var, CoreExpr)]
binds2
| let matchExpr :: (Var, CoreExpr) -> Bool
matchExpr (Var
bndr,CoreExpr
expr) =
(Bool -> Bool
not Bool
top Bool -> Bool -> Bool
|| [SDoc] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (RnEnv2 -> Var -> Var -> [SDoc]
diffIdInfo RnEnv2
env Var
bndr Var
bndr1)) Bool -> Bool -> Bool
&&
[SDoc] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
bndr1 Var
bndr) CoreExpr
expr1 CoreExpr
expr)
, ([(Var, CoreExpr)]
binds2l, (Var
bndr2,CoreExpr
_):[(Var, CoreExpr)]
binds2r) <- ((Var, CoreExpr) -> Bool)
-> [(Var, CoreExpr)] -> ([(Var, CoreExpr)], [(Var, CoreExpr)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Var, CoreExpr) -> Bool
matchExpr [(Var, CoreExpr)]
binds2
= Int
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
go ([(Var, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Var, CoreExpr)]
binds1) (RnEnv2 -> Var -> Var -> RnEnv2
rnBndr2 RnEnv2
env Var
bndr1 Var
bndr2)
[(Var, CoreExpr)]
binds1 ([(Var, CoreExpr)]
binds2l [(Var, CoreExpr)] -> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a. [a] -> [a] -> [a]
++ [(Var, CoreExpr)]
binds2r)
| Bool
otherwise
= Int
-> RnEnv2
-> [(Var, CoreExpr)]
-> [(Var, CoreExpr)]
-> ([SDoc], RnEnv2)
go (Int
fuelInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) RnEnv2
env ([(Var, CoreExpr)]
binds1[(Var, CoreExpr)] -> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a. [a] -> [a] -> [a]
++[(Var
bndr1,CoreExpr
expr1)]) [(Var, CoreExpr)]
binds2
go Int
_ RnEnv2
_ [(Var, CoreExpr)]
_ [(Var, CoreExpr)]
_ = String -> ([SDoc], RnEnv2)
forall a. String -> a
panic String
"diffBinds: impossible"
warn :: RnEnv2 -> [(Var, CoreExpr)] -> [(Var, CoreExpr)] -> [SDoc]
warn RnEnv2
env [(Var, CoreExpr)]
binds1 [(Var, CoreExpr)]
binds2 =
(((Var, CoreExpr), (Var, CoreExpr)) -> [SDoc])
-> [((Var, CoreExpr), (Var, CoreExpr))] -> [SDoc]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((Var, CoreExpr) -> (Var, CoreExpr) -> [SDoc])
-> ((Var, CoreExpr), (Var, CoreExpr)) -> [SDoc]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (RnEnv2 -> (Var, CoreExpr) -> (Var, CoreExpr) -> [SDoc]
diffBind RnEnv2
env)) ([(Var, CoreExpr)]
-> [(Var, CoreExpr)] -> [((Var, CoreExpr), (Var, CoreExpr))]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Var, CoreExpr)]
binds1' [(Var, CoreExpr)]
binds2') [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++
String -> [(Var, CoreExpr)] -> [SDoc]
forall {b}. OutputableBndr b => String -> [(b, Expr b)] -> [SDoc]
unmatched String
"unmatched left-hand:" (Int -> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a. Int -> [a] -> [a]
drop Int
l [(Var, CoreExpr)]
binds1') [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++
String -> [(Var, CoreExpr)] -> [SDoc]
forall {b}. OutputableBndr b => String -> [(b, Expr b)] -> [SDoc]
unmatched String
"unmatched right-hand:" (Int -> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a. Int -> [a] -> [a]
drop Int
l [(Var, CoreExpr)]
binds2')
where binds1' :: [(Var, CoreExpr)]
binds1' = ((Var, CoreExpr) -> (Var, CoreExpr) -> Ordering)
-> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((Var, CoreExpr) -> Var)
-> (Var, CoreExpr) -> (Var, CoreExpr) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst) [(Var, CoreExpr)]
binds1
binds2' :: [(Var, CoreExpr)]
binds2' = ((Var, CoreExpr) -> (Var, CoreExpr) -> Ordering)
-> [(Var, CoreExpr)] -> [(Var, CoreExpr)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((Var, CoreExpr) -> Var)
-> (Var, CoreExpr) -> (Var, CoreExpr) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (Var, CoreExpr) -> Var
forall a b. (a, b) -> a
fst) [(Var, CoreExpr)]
binds2
l :: Int
l = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min ([(Var, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Var, CoreExpr)]
binds1') ([(Var, CoreExpr)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Var, CoreExpr)]
binds2')
unmatched :: String -> [(b, Expr b)] -> [SDoc]
unmatched String
_ [] = []
unmatched String
txt [(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 -> (Var, CoreExpr) -> (Var, CoreExpr) -> [SDoc]
diffBind RnEnv2
env (Var
bndr1,CoreExpr
expr1) (Var
bndr2,CoreExpr
expr2)
| ds :: [SDoc]
ds@(SDoc
_:[SDoc]
_) <- Bool -> RnEnv2 -> CoreExpr -> CoreExpr -> [SDoc]
diffExpr Bool
top RnEnv2
env CoreExpr
expr1 CoreExpr
expr2
= String -> Var -> Var -> [SDoc] -> [SDoc]
locBind String
"in binding" Var
bndr1 Var
bndr2 [SDoc]
ds
| Bool
otherwise
= RnEnv2 -> Var -> Var -> [SDoc]
diffIdInfo RnEnv2
env Var
bndr1 Var
bndr2
diffIdInfo :: RnEnv2 -> Var -> Var -> [SDoc]
diffIdInfo :: RnEnv2 -> Var -> Var -> [SDoc]
diffIdInfo RnEnv2
env Var
bndr1 Var
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 -> Var -> Var -> [SDoc] -> [SDoc]
locBind String
"in unfolding of" Var
bndr1 Var
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 -> Var -> Var -> [SDoc] -> [SDoc]
locBind String
"in Id info of" Var
bndr1 Var
bndr2
[[SDoc] -> SDoc
fsep [BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
bndr1, String -> SDoc
text String
"/=", BindingSite -> Var -> SDoc
forall a. OutputableBndr a => BindingSite -> a -> SDoc
pprBndr BindingSite
LetBind Var
bndr2]]
where info1 :: IdInfo
info1 = HasDebugCallStack => Var -> IdInfo
Var -> IdInfo
idInfo Var
bndr1; info2 :: IdInfo
info2 = HasDebugCallStack => Var -> IdInfo
Var -> IdInfo
idInfo Var
bndr2
diffUnfold :: RnEnv2 -> Unfolding -> Unfolding -> [SDoc]
diffUnfold :: RnEnv2 -> Unfolding -> Unfolding -> [SDoc]
diffUnfold RnEnv2
_ Unfolding
NoUnfolding Unfolding
NoUnfolding = []
diffUnfold RnEnv2
_ Unfolding
BootUnfolding Unfolding
BootUnfolding = []
diffUnfold RnEnv2
_ (OtherCon [AltCon]
cs1) (OtherCon [AltCon]
cs2) | [AltCon]
cs1 [AltCon] -> [AltCon] -> Bool
forall a. Eq a => a -> a -> Bool
== [AltCon]
cs2 = []
diffUnfold RnEnv2
env (DFunUnfolding [Var]
bs1 DataCon
c1 [CoreExpr]
a1)
(DFunUnfolding [Var]
bs2 DataCon
c2 [CoreExpr]
a2)
| DataCon
c1 DataCon -> DataCon -> Bool
forall a. Eq a => a -> a -> Bool
== DataCon
c2 Bool -> Bool -> Bool
&& [Var] -> [Var] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [Var]
bs1 [Var]
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 -> [Var] -> [Var] -> RnEnv2
rnBndrs2 RnEnv2
env [Var]
bs1 [Var]
bs2
diffUnfold RnEnv2
env (CoreUnfolding CoreExpr
t1 UnfoldingSource
_ Bool
_ Bool
v1 Bool
cl1 Bool
wf1 Bool
x1 UnfoldingGuidance
g1)
(CoreUnfolding CoreExpr
t2 UnfoldingSource
_ Bool
_ Bool
v2 Bool
cl2 Bool
wf2 Bool
x2 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 RnEnv2
_ Unfolding
uf1 Unfolding
uf2
= [[SDoc] -> SDoc
fsep [Unfolding -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unfolding
uf1, String -> SDoc
text String
"/=", Unfolding -> SDoc
forall a. Outputable a => a -> SDoc
ppr Unfolding
uf2]]
locBind :: String -> Var -> Var -> [SDoc] -> [SDoc]
locBind :: String -> Var -> Var -> [SDoc] -> [SDoc]
locBind String
loc Var
b1 Var
b2 [SDoc]
diffs = (SDoc -> SDoc) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map SDoc -> SDoc
addLoc [SDoc]
diffs
where addLoc :: SDoc -> SDoc
addLoc SDoc
d = SDoc
d SDoc -> SDoc -> SDoc
$$ Int -> SDoc -> SDoc
nest Int
2 (SDoc -> SDoc
parens (String -> SDoc
text String
loc SDoc -> SDoc -> SDoc
<+> SDoc
bindLoc))
bindLoc :: SDoc
bindLoc | Var
b1 Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
b2 = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
b1
| Bool
otherwise = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
b1 SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'/' SDoc -> SDoc -> SDoc
<> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
b2
tryEtaReduce :: [Var] -> CoreExpr -> Maybe CoreExpr
tryEtaReduce :: [Var] -> CoreExpr -> Maybe CoreExpr
tryEtaReduce [Var]
bndrs CoreExpr
body
= [Var] -> CoreExpr -> CoercionR -> Maybe CoreExpr
go ([Var] -> [Var]
forall a. [a] -> [a]
reverse [Var]
bndrs) CoreExpr
body (Type -> CoercionR
mkRepReflCo (CoreExpr -> Type
exprType CoreExpr
body))
where
incoming_arity :: Int
incoming_arity = (Var -> Bool) -> [Var] -> Int
forall a. (a -> Bool) -> [a] -> Int
count Var -> Bool
isId [Var]
bndrs
go :: [Var]
-> CoreExpr
-> Coercion
-> Maybe CoreExpr
go :: [Var] -> CoreExpr -> CoercionR -> Maybe CoreExpr
go [] CoreExpr
fun CoercionR
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` CoercionR -> VarSet
tyCoVarsOfCo CoercionR
co
, Bool -> Bool
not ((Var -> Bool) -> [Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Var -> VarSet -> Bool
`elemVarSet` VarSet
used_vars) [Var]
bndrs)
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> CoercionR -> CoreExpr
mkCast CoreExpr
fun CoercionR
co)
go [Var]
bs (Tick Tickish Var
t CoreExpr
e) CoercionR
co
| Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishFloatable Tickish Var
t
= (CoreExpr -> CoreExpr) -> Maybe CoreExpr -> Maybe CoreExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Tickish Var -> CoreExpr -> CoreExpr
forall b. Tickish Var -> Expr b -> Expr b
Tick Tickish Var
t) (Maybe CoreExpr -> Maybe CoreExpr)
-> Maybe CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Var] -> CoreExpr -> CoercionR -> Maybe CoreExpr
go [Var]
bs CoreExpr
e CoercionR
co
go (Var
b : [Var]
bs) (App CoreExpr
fun CoreExpr
arg) CoercionR
co
| Just (CoercionR
co', [Tickish Var]
ticks) <- Var
-> CoreExpr
-> CoercionR
-> Type
-> Maybe (CoercionR, [Tickish Var])
ok_arg Var
b CoreExpr
arg CoercionR
co (CoreExpr -> Type
exprType CoreExpr
fun)
= (CoreExpr -> CoreExpr) -> Maybe CoreExpr -> Maybe CoreExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((CoreExpr -> [Tickish Var] -> CoreExpr)
-> [Tickish Var] -> CoreExpr -> CoreExpr
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Tickish Var -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Var] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Var -> CoreExpr -> CoreExpr
mkTick) [Tickish Var]
ticks) (Maybe CoreExpr -> Maybe CoreExpr)
-> Maybe CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Var] -> CoreExpr -> CoercionR -> Maybe CoreExpr
go [Var]
bs CoreExpr
fun CoercionR
co'
go [Var]
_ CoreExpr
_ CoercionR
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
ok_fun :: Expr b -> Bool
ok_fun (App Expr b
fun (Type {})) = Expr b -> Bool
ok_fun Expr b
fun
ok_fun (Cast Expr b
fun CoercionR
_) = Expr b -> Bool
ok_fun Expr b
fun
ok_fun (Tick Tickish Var
_ Expr b
expr) = Expr b -> Bool
ok_fun Expr b
expr
ok_fun (Var Var
fun_id) = Var -> Bool
ok_fun_id Var
fun_id Bool -> Bool -> Bool
|| (Var -> Bool) -> [Var] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Var -> Bool
ok_lam [Var]
bndrs
ok_fun Expr b
_fun = Bool
False
ok_fun_id :: Var -> Bool
ok_fun_id Var
fun = Var -> Int
fun_arity Var
fun Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
incoming_arity
fun_arity :: Var -> Int
fun_arity Var
fun
| Var -> Bool
isLocalId Var
fun
, OccInfo -> Bool
isStrongLoopBreaker (Var -> OccInfo
idOccInfo Var
fun) = Int
0
| Int
arity Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int
arity
| Unfolding -> Bool
isEvaldUnfolding (Var -> Unfolding
idUnfolding Var
fun) = Int
1
| Bool
otherwise = Int
0
where
arity :: Int
arity = Var -> Int
idArity Var
fun
ok_lam :: Var -> Bool
ok_lam Var
v = Var -> Bool
isTyVar Var
v Bool -> Bool -> Bool
|| Var -> Bool
isEvVar Var
v
ok_arg :: Var
-> CoreExpr
-> Coercion
-> Type
-> Maybe (Coercion
, [Tickish Var])
ok_arg :: Var
-> CoreExpr
-> CoercionR
-> Type
-> Maybe (CoercionR, [Tickish Var])
ok_arg Var
bndr (Type Type
ty) CoercionR
co Type
_
| Just Var
tv <- Type -> Maybe Var
getTyVar_maybe Type
ty
, Var
bndr Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
tv = (CoercionR, [Tickish Var]) -> Maybe (CoercionR, [Tickish Var])
forall a. a -> Maybe a
Just ([Var] -> CoercionR -> CoercionR
mkHomoForAllCos [Var
tv] CoercionR
co, [])
ok_arg Var
bndr (Var Var
v) CoercionR
co Type
fun_ty
| Var
bndr Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
v
, let mult :: Type
mult = Var -> Type
idMult Var
bndr
, Just (Type
fun_mult, Type
_, Type
_) <- Type -> Maybe (Type, Type, Type)
splitFunTy_maybe Type
fun_ty
, Type
mult Type -> Type -> Bool
`eqType` Type
fun_mult
= let reflCo :: CoercionR
reflCo = Type -> CoercionR
mkRepReflCo (Var -> Type
idType Var
bndr)
in (CoercionR, [Tickish Var]) -> Maybe (CoercionR, [Tickish Var])
forall a. a -> Maybe a
Just (Role -> CoercionR -> CoercionR -> CoercionR -> CoercionR
mkFunCo Role
Representational (Type -> CoercionR
multToCo Type
mult) CoercionR
reflCo CoercionR
co, [])
ok_arg Var
bndr (Cast CoreExpr
e CoercionR
co_arg) CoercionR
co Type
fun_ty
| ([Tickish Var]
ticks, Var Var
v) <- (Tickish Var -> Bool) -> CoreExpr -> ([Tickish Var], CoreExpr)
forall b.
(Tickish Var -> Bool) -> Expr b -> ([Tickish Var], Expr b)
stripTicksTop Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishFloatable CoreExpr
e
, Just (Type
fun_mult, Type
_, Type
_) <- Type -> Maybe (Type, Type, Type)
splitFunTy_maybe Type
fun_ty
, Var
bndr Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
== Var
v
, Type
fun_mult Type -> Type -> Bool
`eqType` Var -> Type
idMult Var
bndr
= (CoercionR, [Tickish Var]) -> Maybe (CoercionR, [Tickish Var])
forall a. a -> Maybe a
Just (Role -> CoercionR -> CoercionR -> CoercionR -> CoercionR
mkFunCo Role
Representational (Type -> CoercionR
multToCo Type
fun_mult) (CoercionR -> CoercionR
mkSymCo CoercionR
co_arg) CoercionR
co, [Tickish Var]
ticks)
ok_arg Var
bndr (Tick Tickish Var
t CoreExpr
arg) CoercionR
co Type
fun_ty
| Tickish Var -> Bool
forall id. Tickish id -> Bool
tickishFloatable Tickish Var
t, Just (CoercionR
co', [Tickish Var]
ticks) <- Var
-> CoreExpr
-> CoercionR
-> Type
-> Maybe (CoercionR, [Tickish Var])
ok_arg Var
bndr CoreExpr
arg CoercionR
co Type
fun_ty
= (CoercionR, [Tickish Var]) -> Maybe (CoercionR, [Tickish Var])
forall a. a -> Maybe a
Just (CoercionR
co', Tickish Var
tTickish Var -> [Tickish Var] -> [Tickish Var]
forall a. a -> [a] -> [a]
:[Tickish Var]
ticks)
ok_arg Var
_ CoreExpr
_ CoercionR
_ Type
_ = Maybe (CoercionR, [Tickish Var])
forall a. Maybe a
Nothing
isEmptyTy :: Type -> Bool
isEmptyTy :: Type -> Bool
isEmptyTy Type
ty
| Just (TyCon
tc, [Type]
inst_tys) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty
, Just [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 CoreExpr
e
| (fun :: CoreExpr
fun@(Var Var
b), [Type Type
t, CoreExpr
loc, CoreExpr
arg], [Tickish Var]
_) <- (Tickish Var -> Bool)
-> CoreExpr -> (CoreExpr, [CoreExpr], [Tickish Var])
forall b.
(Tickish Var -> Bool)
-> Expr b -> (Expr b, [Expr b], [Tickish Var])
collectArgsTicks (Bool -> Tickish Var -> Bool
forall a b. a -> b -> a
const Bool
True) CoreExpr
e
, Var -> Name
idName Var
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 CoreExpr
_ = Maybe (CoreExpr, Type, CoreExpr, CoreExpr)
forall a. Maybe a
Nothing
isJoinBind :: CoreBind -> Bool
isJoinBind :: Bind Var -> Bool
isJoinBind (NonRec Var
b CoreExpr
_) = Var -> Bool
isJoinId Var
b
isJoinBind (Rec ((Var
b, CoreExpr
_) : [(Var, CoreExpr)]
_)) = Var -> Bool
isJoinId Var
b
isJoinBind Bind Var
_ = Bool
False
dumpIdInfoOfProgram :: (IdInfo -> SDoc) -> CoreProgram -> SDoc
dumpIdInfoOfProgram :: (IdInfo -> SDoc) -> [Bind Var] -> SDoc
dumpIdInfoOfProgram IdInfo -> SDoc
ppr_id_info [Bind Var]
binds = [SDoc] -> SDoc
vcat ((Var -> SDoc) -> [Var] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Var -> SDoc
printId [Var]
ids)
where
ids :: [Var]
ids = (Var -> Var -> Ordering) -> [Var] -> [Var]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (Name -> Name -> Ordering
stableNameCmp (Name -> Name -> Ordering)
-> (Var -> Name) -> Var -> Var -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Var -> Name
forall a. NamedThing a => a -> Name
getName) ((Bind Var -> [Var]) -> [Bind Var] -> [Var]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Bind Var -> [Var]
forall {b}. Bind b -> [b]
getIds [Bind Var]
binds)
getIds :: Bind b -> [b]
getIds (NonRec b
i Expr b
_) = [ b
i ]
getIds (Rec [(b, Expr b)]
bs) = ((b, Expr b) -> b) -> [(b, Expr b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (b, Expr b) -> b
forall a b. (a, b) -> a
fst [(b, Expr b)]
bs
printId :: Var -> SDoc
printId Var
id | Var -> Bool
isExportedId Var
id = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
id SDoc -> SDoc -> SDoc
<> SDoc
colon SDoc -> SDoc -> SDoc
<+> (IdInfo -> SDoc
ppr_id_info (HasDebugCallStack => Var -> IdInfo
Var -> IdInfo
idInfo Var
id))
| Bool
otherwise = SDoc
empty
isUnsafeEqualityProof :: CoreExpr -> Bool
isUnsafeEqualityProof :: CoreExpr -> Bool
isUnsafeEqualityProof CoreExpr
e
| Var Var
v `App` Type Type
_ `App` Type Type
_ `App` Type Type
_ <- CoreExpr
e
= Var -> Name
idName Var
v Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
unsafeEqualityProofName
| Bool
otherwise
= Bool
False