{-# LANGUAGE CPP, RankNTypes, PatternSynonyms, ViewPatterns, RecordWildCards,
DeriveFunctor #-}
{-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-}
module PrelRules
( primOpRules
, builtinRules
, caseRules
)
where
#include "GhclibHsVersions.h"
import GhcPrelude
import {-# SOURCE #-} MkId ( mkPrimOpId, magicDictId )
import CoreSyn
import MkCore
import Id
import Literal
import CoreOpt ( exprIsLiteral_maybe )
import PrimOp ( PrimOp(..), tagToEnumKey )
import TysWiredIn
import TysPrim
import TyCon ( tyConDataCons_maybe, isAlgTyCon, isEnumerationTyCon
, isNewTyCon, unwrapNewTyCon_maybe, tyConDataCons
, tyConFamilySize )
import DataCon ( dataConTagZ, dataConTyCon, dataConWorkId )
import CoreUtils ( cheapEqExpr, cheapEqExpr', exprIsHNF, exprType, stripTicksTop, stripTicksTopT, mkTicks )
import CoreUnfold ( exprIsConApp_maybe )
import Type
import OccName ( occNameFS )
import PrelNames
import Maybes ( orElse )
import Name ( Name, nameOccName )
import Outputable
import FastString
import BasicTypes
import DynFlags
import GHC.Platform
import Util
import Coercion (mkUnbranchedAxInstCo,mkSymCo,Role(..))
import Control.Applicative ( Alternative(..) )
import Control.Monad
import qualified Control.Monad.Fail as MonadFail
import Data.Bits as Bits
import qualified Data.ByteString as BS
import Data.Int
import Data.Ratio
import Data.Word
primOpRules :: Name -> PrimOp -> Maybe CoreRule
primOpRules :: Name -> PrimOp -> Maybe CoreRule
primOpRules Name
nm PrimOp
TagToEnumOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ RuleM CoreExpr
tagToEnumRule ]
primOpRules Name
nm PrimOp
DataToTagOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ RuleM CoreExpr
dataToTagRule ]
primOpRules Name
nm PrimOp
IntAddOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+))
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
zeroi
, PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
IntAddOp DynFlags -> PrimOps
intPrimOps
]
primOpRules Name
nm PrimOp
IntSubOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 (-))
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
zeroi
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zeroi
, PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
IntSubOp DynFlags -> PrimOps
intPrimOps
]
primOpRules Name
nm PrimOp
IntAddCOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOpC2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+))
, (DynFlags -> Literal) -> RuleM CoreExpr
identityCDynFlags DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
IntSubCOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOpC2 (-))
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityCDynFlags DynFlags -> Literal
zeroi
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLitNoC DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
IntMulOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*))
, (DynFlags -> Literal) -> RuleM CoreExpr
zeroElem DynFlags -> Literal
zeroi
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
onei
, PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
IntMulOp DynFlags -> PrimOps
intPrimOps
]
primOpRules Name
nm PrimOp
IntQuotOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ Int -> RuleM ()
nonZeroLit Int
1 RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
quot)
, (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
zeroi
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
onei
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
onei ]
primOpRules Name
nm PrimOp
IntRemOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ Int -> RuleM ()
nonZeroLit Int
1 RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
rem)
, (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
zeroi
, do Literal
l <- Int -> RuleM Literal
getLiteral Int
1
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Literal
l Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
onei DynFlags
dflags)
(DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zeroi
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zeroi
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
AndIOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
(.&.))
, RuleM CoreExpr
idempotent
, (DynFlags -> Literal) -> RuleM CoreExpr
zeroElem DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
OrIOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
(.|.))
, RuleM CoreExpr
idempotent
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
XorIOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor)
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
zeroi
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
NotIOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit DynFlags -> Literal -> Maybe CoreExpr
complementOp
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
NotIOp ]
primOpRules Name
nm PrimOp
IntNegOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit DynFlags -> Literal -> Maybe CoreExpr
negOp
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
IntNegOp ]
primOpRules Name
nm PrimOp
ISllOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule ((Integer -> Int -> Integer)
-> DynFlags -> Integer -> Int -> Integer
forall a b. a -> b -> a
const Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
Bits.shiftL)
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
ISraOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule ((Integer -> Int -> Integer)
-> DynFlags -> Integer -> Int -> Integer
forall a b. a -> b -> a
const Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
Bits.shiftR)
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
ISrlOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule DynFlags -> Integer -> Int -> Integer
shiftRightLogical
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
WordAddOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+))
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
zerow
, PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
WordAddOp DynFlags -> PrimOps
wordPrimOps
]
primOpRules Name
nm PrimOp
WordSubOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 (-))
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
zerow
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zerow
, PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
WordSubOp DynFlags -> PrimOps
wordPrimOps
]
primOpRules Name
nm PrimOp
WordAddCOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOpC2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+))
, (DynFlags -> Literal) -> RuleM CoreExpr
identityCDynFlags DynFlags -> Literal
zerow ]
primOpRules Name
nm PrimOp
WordSubCOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOpC2 (-))
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityCDynFlags DynFlags -> Literal
zerow
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLitNoC DynFlags -> Literal
zerow ]
primOpRules Name
nm PrimOp
WordMulOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*))
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
onew
, PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
WordMulOp DynFlags -> PrimOps
wordPrimOps
]
primOpRules Name
nm PrimOp
WordQuotOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ Int -> RuleM ()
nonZeroLit Int
1 RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
quot)
, (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
onew ]
primOpRules Name
nm PrimOp
WordRemOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ Int -> RuleM ()
nonZeroLit Int
1 RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
rem)
, (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
zerow
, do Literal
l <- Int -> RuleM Literal
getLiteral Int
1
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Literal
l Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
onew DynFlags
dflags)
(DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zerow
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zerow ]
primOpRules Name
nm PrimOp
AndOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
(.&.))
, RuleM CoreExpr
idempotent
, (DynFlags -> Literal) -> RuleM CoreExpr
zeroElem DynFlags -> Literal
zerow ]
primOpRules Name
nm PrimOp
OrOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
(.|.))
, RuleM CoreExpr
idempotent
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
zerow ]
primOpRules Name
nm PrimOp
XorOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor)
, (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
zerow
, RuleM ()
equalArgs RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
zerow ]
primOpRules Name
nm PrimOp
NotOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit DynFlags -> Literal -> Maybe CoreExpr
complementOp
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
NotOp ]
primOpRules Name
nm PrimOp
SllOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule ((Integer -> Int -> Integer)
-> DynFlags -> Integer -> Int -> Integer
forall a b. a -> b -> a
const Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
Bits.shiftL) ]
primOpRules Name
nm PrimOp
SrlOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule DynFlags -> Integer -> Int -> Integer
shiftRightLogical ]
primOpRules Name
nm PrimOp
Word2IntOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Literal) -> RuleM CoreExpr
liftLitDynFlags DynFlags -> Literal -> Literal
word2IntLit
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
Int2WordOp ]
primOpRules Name
nm PrimOp
Int2WordOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Literal) -> RuleM CoreExpr
liftLitDynFlags DynFlags -> Literal -> Literal
int2WordLit
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
Word2IntOp ]
primOpRules Name
nm PrimOp
Narrow8IntOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
narrow8IntLit
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow8IntOp
, PrimOp
Narrow8IntOp PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
Narrow16IntOp
, PrimOp
Narrow8IntOp PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
Narrow32IntOp ]
primOpRules Name
nm PrimOp
Narrow16IntOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
narrow16IntLit
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow8IntOp
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow16IntOp
, PrimOp
Narrow16IntOp PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
Narrow32IntOp ]
primOpRules Name
nm PrimOp
Narrow32IntOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
narrow32IntLit
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow8IntOp
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow16IntOp
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow32IntOp
, RuleM CoreExpr
removeOp32 ]
primOpRules Name
nm PrimOp
Narrow8WordOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
narrow8WordLit
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow8WordOp
, PrimOp
Narrow8WordOp PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
Narrow16WordOp
, PrimOp
Narrow8WordOp PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
Narrow32WordOp ]
primOpRules Name
nm PrimOp
Narrow16WordOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
narrow16WordLit
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow8WordOp
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow16WordOp
, PrimOp
Narrow16WordOp PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
Narrow32WordOp ]
primOpRules Name
nm PrimOp
Narrow32WordOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
narrow32WordLit
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow8WordOp
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow16WordOp
, PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
Narrow32WordOp
, RuleM CoreExpr
removeOp32 ]
primOpRules Name
nm PrimOp
OrdOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
char2IntLit
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
ChrOp ]
primOpRules Name
nm PrimOp
ChrOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ do [Lit Literal
lit] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Literal -> Bool
litFitsInChar Literal
lit)
(Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
int2CharLit
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
OrdOp ]
primOpRules Name
nm PrimOp
Float2IntOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
float2IntLit ]
primOpRules Name
nm PrimOp
Int2FloatOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
int2FloatLit ]
primOpRules Name
nm PrimOp
Double2IntOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
double2IntLit ]
primOpRules Name
nm PrimOp
Int2DoubleOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
int2DoubleLit ]
primOpRules Name
nm PrimOp
Float2DoubleOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
float2DoubleLit ]
primOpRules Name
nm PrimOp
Double2FloatOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
double2FloatLit ]
primOpRules Name
nm PrimOp
FloatAddOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
floatOp2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
(+))
, Literal -> RuleM CoreExpr
identity Literal
zerof ]
primOpRules Name
nm PrimOp
FloatSubOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
floatOp2 (-))
, Literal -> RuleM CoreExpr
rightIdentity Literal
zerof ]
primOpRules Name
nm PrimOp
FloatMulOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
floatOp2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
(*))
, Literal -> RuleM CoreExpr
identity Literal
onef
, Literal -> PrimOp -> RuleM CoreExpr
strengthReduction Literal
twof PrimOp
FloatAddOp ]
primOpRules Name
nm PrimOp
FloatDivOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ RuleM ()
guardFloatDiv RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
floatOp2 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
(/))
, Literal -> RuleM CoreExpr
rightIdentity Literal
onef ]
primOpRules Name
nm PrimOp
FloatNegOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit DynFlags -> Literal -> Maybe CoreExpr
negOp
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
FloatNegOp ]
primOpRules Name
nm PrimOp
DoubleAddOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
doubleOp2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
(+))
, Literal -> RuleM CoreExpr
identity Literal
zerod ]
primOpRules Name
nm PrimOp
DoubleSubOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
doubleOp2 (-))
, Literal -> RuleM CoreExpr
rightIdentity Literal
zerod ]
primOpRules Name
nm PrimOp
DoubleMulOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
doubleOp2 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
(*))
, Literal -> RuleM CoreExpr
identity Literal
oned
, Literal -> PrimOp -> RuleM CoreExpr
strengthReduction Literal
twod PrimOp
DoubleAddOp ]
primOpRules Name
nm PrimOp
DoubleDivOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ RuleM ()
guardDoubleDiv RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
doubleOp2 Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
(/))
, Literal -> RuleM CoreExpr
rightIdentity Literal
oned ]
primOpRules Name
nm PrimOp
DoubleNegOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
1 [ (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit DynFlags -> Literal -> Maybe CoreExpr
negOp
, PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
DoubleNegOp ]
primOpRules Name
nm PrimOp
IntEqOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(==) [ Bool -> RuleM CoreExpr
litEq Bool
True ]
primOpRules Name
nm PrimOp
IntNeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(/=) [ Bool -> RuleM CoreExpr
litEq Bool
False ]
primOpRules Name
nm PrimOp
CharEqOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(==) [ Bool -> RuleM CoreExpr
litEq Bool
True ]
primOpRules Name
nm PrimOp
CharNeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(/=) [ Bool -> RuleM CoreExpr
litEq Bool
False ]
primOpRules Name
nm PrimOp
IntGtOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Gt ]
primOpRules Name
nm PrimOp
IntGeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>=) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Ge ]
primOpRules Name
nm PrimOp
IntLeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<=) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Le ]
primOpRules Name
nm PrimOp
IntLtOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Lt ]
primOpRules Name
nm PrimOp
CharGtOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Gt ]
primOpRules Name
nm PrimOp
CharGeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>=) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Ge ]
primOpRules Name
nm PrimOp
CharLeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<=) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Le ]
primOpRules Name
nm PrimOp
CharLtOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Lt ]
primOpRules Name
nm PrimOp
FloatGtOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>)
primOpRules Name
nm PrimOp
FloatGeOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>=)
primOpRules Name
nm PrimOp
FloatLeOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<=)
primOpRules Name
nm PrimOp
FloatLtOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<)
primOpRules Name
nm PrimOp
FloatEqOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(==)
primOpRules Name
nm PrimOp
FloatNeOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(/=)
primOpRules Name
nm PrimOp
DoubleGtOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>)
primOpRules Name
nm PrimOp
DoubleGeOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>=)
primOpRules Name
nm PrimOp
DoubleLeOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<=)
primOpRules Name
nm PrimOp
DoubleLtOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<)
primOpRules Name
nm PrimOp
DoubleEqOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(==)
primOpRules Name
nm PrimOp
DoubleNeOp = Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(/=)
primOpRules Name
nm PrimOp
WordGtOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Gt ]
primOpRules Name
nm PrimOp
WordGeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(>=) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Ge ]
primOpRules Name
nm PrimOp
WordLeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<=) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Le ]
primOpRules Name
nm PrimOp
WordLtOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
(<) [ Comparison -> RuleM CoreExpr
boundsCmp Comparison
Lt ]
primOpRules Name
nm PrimOp
WordEqOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(==) [ Bool -> RuleM CoreExpr
litEq Bool
True ]
primOpRules Name
nm PrimOp
WordNeOp = Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Eq a => a -> a -> Bool
forall a. Ord a => a -> a -> Bool
(/=) [ Bool -> RuleM CoreExpr
litEq Bool
False ]
primOpRules Name
nm PrimOp
AddrAddOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [ (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
zeroi ]
primOpRules Name
nm PrimOp
SeqOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
4 [ RuleM CoreExpr
seqRule ]
primOpRules Name
nm PrimOp
SparkOp = Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
4 [ RuleM CoreExpr
sparkRule ]
primOpRules Name
_ PrimOp
_ = Maybe CoreRule
forall a. Maybe a
Nothing
mkPrimOpRule :: Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule :: Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
arity [RuleM CoreExpr]
rules = CoreRule -> Maybe CoreRule
forall a. a -> Maybe a
Just (CoreRule -> Maybe CoreRule) -> CoreRule -> Maybe CoreRule
forall a b. (a -> b) -> a -> b
$ Name -> Int -> RuleM CoreExpr -> CoreRule
mkBasicRule Name
nm Int
arity ([RuleM CoreExpr] -> RuleM CoreExpr
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [RuleM CoreExpr]
rules)
mkRelOpRule :: Name -> (forall a . Ord a => a -> a -> Bool)
-> [RuleM CoreExpr] -> Maybe CoreRule
mkRelOpRule :: Name
-> (forall a. Ord a => a -> a -> Bool)
-> [RuleM CoreExpr]
-> Maybe CoreRule
mkRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
cmp [RuleM CoreExpr]
extra
= Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 ([RuleM CoreExpr] -> Maybe CoreRule)
-> [RuleM CoreExpr] -> Maybe CoreRule
forall a b. (a -> b) -> a -> b
$
(forall a. Ord a => a -> a -> Bool) -> RuleM CoreExpr
binaryCmpLit forall a. Ord a => a -> a -> Bool
cmp RuleM CoreExpr -> [RuleM CoreExpr] -> [RuleM CoreExpr]
forall a. a -> [a] -> [a]
: RuleM CoreExpr
equal_rule RuleM CoreExpr -> [RuleM CoreExpr] -> [RuleM CoreExpr]
forall a. a -> [a] -> [a]
: [RuleM CoreExpr]
extra
where
equal_rule :: RuleM CoreExpr
equal_rule = do { RuleM ()
equalArgs
; DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (if Bool -> Bool -> Bool
forall a. Ord a => a -> a -> Bool
cmp Bool
True Bool
True
then DynFlags -> CoreExpr
trueValInt DynFlags
dflags
else DynFlags -> CoreExpr
falseValInt DynFlags
dflags) }
mkFloatingRelOpRule :: Name -> (forall a . Ord a => a -> a -> Bool)
-> Maybe CoreRule
mkFloatingRelOpRule :: Name -> (forall a. Ord a => a -> a -> Bool) -> Maybe CoreRule
mkFloatingRelOpRule Name
nm forall a. Ord a => a -> a -> Bool
cmp
= Name -> Int -> [RuleM CoreExpr] -> Maybe CoreRule
mkPrimOpRule Name
nm Int
2 [(forall a. Ord a => a -> a -> Bool) -> RuleM CoreExpr
binaryCmpLit forall a. Ord a => a -> a -> Bool
cmp]
zeroi, onei, zerow, onew :: DynFlags -> Literal
zeroi :: DynFlags -> Literal
zeroi DynFlags
dflags = DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags Integer
0
onei :: DynFlags -> Literal
onei DynFlags
dflags = DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags Integer
1
zerow :: DynFlags -> Literal
zerow DynFlags
dflags = DynFlags -> Integer -> Literal
mkLitWord DynFlags
dflags Integer
0
onew :: DynFlags -> Literal
onew DynFlags
dflags = DynFlags -> Integer -> Literal
mkLitWord DynFlags
dflags Integer
1
zerof, onef, twof, zerod, oned, twod :: Literal
zerof :: Literal
zerof = Rational -> Literal
mkLitFloat Rational
0.0
onef :: Literal
onef = Rational -> Literal
mkLitFloat Rational
1.0
twof :: Literal
twof = Rational -> Literal
mkLitFloat Rational
2.0
zerod :: Literal
zerod = Rational -> Literal
mkLitDouble Rational
0.0
oned :: Literal
oned = Rational -> Literal
mkLitDouble Rational
1.0
twod :: Literal
twod = Rational -> Literal
mkLitDouble Rational
2.0
cmpOp :: DynFlags -> (forall a . Ord a => a -> a -> Bool)
-> Literal -> Literal -> Maybe CoreExpr
cmpOp :: DynFlags
-> (forall a. Ord a => a -> a -> Bool)
-> Literal
-> Literal
-> Maybe CoreExpr
cmpOp DynFlags
dflags forall a. Ord a => a -> a -> Bool
cmp = Literal -> Literal -> Maybe CoreExpr
go
where
done :: Bool -> Maybe CoreExpr
done Bool
True = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
trueValInt DynFlags
dflags
done Bool
False = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
falseValInt DynFlags
dflags
go :: Literal -> Literal -> Maybe CoreExpr
go (LitChar Char
i1) (LitChar Char
i2) = Bool -> Maybe CoreExpr
done (Char
i1 Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
`cmp` Char
i2)
go (LitFloat Rational
i1) (LitFloat Rational
i2) = Bool -> Maybe CoreExpr
done (Rational
i1 Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
`cmp` Rational
i2)
go (LitDouble Rational
i1) (LitDouble Rational
i2) = Bool -> Maybe CoreExpr
done (Rational
i1 Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
`cmp` Rational
i2)
go (LitNumber LitNumType
nt1 Integer
i1 Type
_) (LitNumber LitNumType
nt2 Integer
i2 Type
_)
| LitNumType
nt1 LitNumType -> LitNumType -> Bool
forall a. Eq a => a -> a -> Bool
/= LitNumType
nt2 = Maybe CoreExpr
forall a. Maybe a
Nothing
| Bool
otherwise = Bool -> Maybe CoreExpr
done (Integer
i1 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
`cmp` Integer
i2)
go Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
negOp :: DynFlags -> Literal -> Maybe CoreExpr
negOp :: DynFlags -> Literal -> Maybe CoreExpr
negOp DynFlags
_ (LitFloat Rational
0.0) = Maybe CoreExpr
forall a. Maybe a
Nothing
negOp DynFlags
dflags (LitFloat Rational
f) = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> Rational -> CoreExpr
mkFloatVal DynFlags
dflags (-Rational
f))
negOp DynFlags
_ (LitDouble Rational
0.0) = Maybe CoreExpr
forall a. Maybe a
Nothing
negOp DynFlags
dflags (LitDouble Rational
d) = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> Rational -> CoreExpr
mkDoubleVal DynFlags
dflags (-Rational
d))
negOp DynFlags
dflags (LitNumber LitNumType
nt Integer
i Type
t)
| LitNumType -> Bool
litNumIsSigned LitNumType
nt = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> LitNumType -> Integer -> Type -> Literal
mkLitNumberWrap DynFlags
dflags LitNumType
nt (-Integer
i) Type
t))
negOp DynFlags
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
complementOp :: DynFlags -> Literal -> Maybe CoreExpr
complementOp :: DynFlags -> Literal -> Maybe CoreExpr
complementOp DynFlags
dflags (LitNumber LitNumType
nt Integer
i Type
t) =
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> LitNumType -> Integer -> Type -> Literal
mkLitNumberWrap DynFlags
dflags LitNumType
nt (Integer -> Integer
forall a. Bits a => a -> a
complement Integer
i) Type
t))
complementOp DynFlags
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
intOp2 :: (Integral a, Integral b)
=> (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 :: (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 = (DynFlags -> a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(DynFlags -> a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2' ((DynFlags -> a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> ((a -> b -> Integer) -> DynFlags -> a -> b -> Integer)
-> (a -> b -> Integer)
-> DynFlags
-> Literal
-> Literal
-> Maybe CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> Integer) -> DynFlags -> a -> b -> Integer
forall a b. a -> b -> a
const
intOp2' :: (Integral a, Integral b)
=> (DynFlags -> a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2' :: (DynFlags -> a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2' DynFlags -> a -> b -> Integer
op DynFlags
dflags (LitNumber LitNumType
LitNumInt Integer
i1 Type
_) (LitNumber LitNumType
LitNumInt Integer
i2 Type
_) =
let o :: a -> b -> Integer
o = DynFlags -> a -> b -> Integer
op DynFlags
dflags
in DynFlags -> Integer -> Maybe CoreExpr
intResult DynFlags
dflags (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
i1 a -> b -> Integer
`o` Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
i2)
intOp2' DynFlags -> a -> b -> Integer
_ DynFlags
_ Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
intOpC2 :: (Integral a, Integral b)
=> (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOpC2 :: (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOpC2 a -> b -> Integer
op DynFlags
dflags (LitNumber LitNumType
LitNumInt Integer
i1 Type
_) (LitNumber LitNumType
LitNumInt Integer
i2 Type
_) = do
DynFlags -> Integer -> Maybe CoreExpr
intCResult DynFlags
dflags (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
i1 a -> b -> Integer
`op` Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
i2)
intOpC2 a -> b -> Integer
_ DynFlags
_ Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
shiftRightLogical :: DynFlags -> Integer -> Int -> Integer
shiftRightLogical :: DynFlags -> Integer -> Int -> Integer
shiftRightLogical DynFlags
dflags Integer
x Int
n =
case Platform -> PlatformWordSize
platformWordSize (DynFlags -> Platform
targetPlatform DynFlags
dflags) of
PlatformWordSize
PW4 -> Word32 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Word32
forall a. Num a => Integer -> a
fromInteger Integer
x Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
n :: Word32)
PlatformWordSize
PW8 -> Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Word64
forall a. Num a => Integer -> a
fromInteger Integer
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
n :: Word64)
retLit :: (DynFlags -> Literal) -> RuleM CoreExpr
retLit :: (DynFlags -> Literal) -> RuleM CoreExpr
retLit DynFlags -> Literal
l = do DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Literal -> CoreExpr) -> Literal -> CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Literal
l DynFlags
dflags
retLitNoC :: (DynFlags -> Literal) -> RuleM CoreExpr
retLitNoC :: (DynFlags -> Literal) -> RuleM CoreExpr
retLitNoC DynFlags -> Literal
l = do DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
let lit :: Literal
lit = DynFlags -> Literal
l DynFlags
dflags
let ty :: Type
ty = Literal -> Type
literalType Literal
lit
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ [Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [Type
ty, Type
ty] [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit, Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Literal
zeroi DynFlags
dflags)]
wordOp2 :: (Integral a, Integral b)
=> (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 :: (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOp2 a -> b -> Integer
op DynFlags
dflags (LitNumber LitNumType
LitNumWord Integer
w1 Type
_) (LitNumber LitNumType
LitNumWord Integer
w2 Type
_)
= DynFlags -> Integer -> Maybe CoreExpr
wordResult DynFlags
dflags (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
w1 a -> b -> Integer
`op` Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
w2)
wordOp2 a -> b -> Integer
_ DynFlags
_ Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
wordOpC2 :: (Integral a, Integral b)
=> (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOpC2 :: (a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
wordOpC2 a -> b -> Integer
op DynFlags
dflags (LitNumber LitNumType
LitNumWord Integer
w1 Type
_) (LitNumber LitNumType
LitNumWord Integer
w2 Type
_) =
DynFlags -> Integer -> Maybe CoreExpr
wordCResult DynFlags
dflags (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
w1 a -> b -> Integer
`op` Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
w2)
wordOpC2 a -> b -> Integer
_ DynFlags
_ Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
shiftRule :: (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule :: (DynFlags -> Integer -> Int -> Integer) -> RuleM CoreExpr
shiftRule DynFlags -> Integer -> Int -> Integer
shift_op
= do { DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; [CoreExpr
e1, Lit (LitNumber LitNumType
LitNumInt Integer
shift_len Type
_)] <- RuleM [CoreExpr]
getArgs
; case CoreExpr
e1 of
CoreExpr
_ | Integer
shift_len Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
-> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e1
| Integer
shift_len Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 Bool -> Bool -> Bool
|| Integer
shift_len Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> DynFlags -> Integer
wordSizeInBits DynFlags
dflags
-> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Literal -> CoreExpr) -> Literal -> CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> LitNumType -> Integer -> Type -> Literal
mkLitNumberWrap DynFlags
dflags LitNumType
LitNumInt Integer
0 (CoreExpr -> Type
exprType CoreExpr
e1)
Lit (LitNumber LitNumType
nt Integer
x Type
t)
| Integer
0 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
shift_len
, Integer
shift_len Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= DynFlags -> Integer
wordSizeInBits DynFlags
dflags
-> let op :: Integer -> Int -> Integer
op = DynFlags -> Integer -> Int -> Integer
shift_op DynFlags
dflags
y :: Integer
y = Integer
x Integer -> Int -> Integer
`op` Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
shift_len
in Maybe CoreExpr -> RuleM CoreExpr
forall a. Maybe a -> RuleM a
liftMaybe (Maybe CoreExpr -> RuleM CoreExpr)
-> Maybe CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> LitNumType -> Integer -> Type -> Literal
mkLitNumberWrap DynFlags
dflags LitNumType
nt Integer
y Type
t))
CoreExpr
_ -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a
mzero }
wordSizeInBits :: DynFlags -> Integer
wordSizeInBits :: DynFlags -> Integer
wordSizeInBits DynFlags
dflags = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Platform -> Int
platformWordSizeInBits (DynFlags -> Platform
targetPlatform DynFlags
dflags))
floatOp2 :: (Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal
-> Maybe (Expr CoreBndr)
floatOp2 :: (Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
floatOp2 Rational -> Rational -> Rational
op DynFlags
dflags (LitFloat Rational
f1) (LitFloat Rational
f2)
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> Rational -> CoreExpr
mkFloatVal DynFlags
dflags (Rational
f1 Rational -> Rational -> Rational
`op` Rational
f2))
floatOp2 Rational -> Rational -> Rational
_ DynFlags
_ Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
doubleOp2 :: (Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal
-> Maybe (Expr CoreBndr)
doubleOp2 :: (Rational -> Rational -> Rational)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
doubleOp2 Rational -> Rational -> Rational
op DynFlags
dflags (LitDouble Rational
f1) (LitDouble Rational
f2)
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> Rational -> CoreExpr
mkDoubleVal DynFlags
dflags (Rational
f1 Rational -> Rational -> Rational
`op` Rational
f2))
doubleOp2 Rational -> Rational -> Rational
_ DynFlags
_ Literal
_ Literal
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
litEq :: Bool
-> RuleM CoreExpr
litEq :: Bool -> RuleM CoreExpr
litEq Bool
is_eq = [RuleM CoreExpr] -> RuleM CoreExpr
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
[ do [Lit Literal
lit, CoreExpr
expr] <- RuleM [CoreExpr]
getArgs
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
DynFlags -> Literal -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *).
(Monad m, Alternative m) =>
DynFlags -> Literal -> CoreExpr -> m CoreExpr
do_lit_eq DynFlags
dflags Literal
lit CoreExpr
expr
, do [CoreExpr
expr, Lit Literal
lit] <- RuleM [CoreExpr]
getArgs
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
DynFlags -> Literal -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *).
(Monad m, Alternative m) =>
DynFlags -> Literal -> CoreExpr -> m CoreExpr
do_lit_eq DynFlags
dflags Literal
lit CoreExpr
expr ]
where
do_lit_eq :: DynFlags -> Literal -> CoreExpr -> m CoreExpr
do_lit_eq DynFlags
dflags Literal
lit CoreExpr
expr = do
Bool -> m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (Literal -> Bool
litIsLifted Literal
lit))
CoreExpr -> m CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> Type -> Type -> [CoreAlt] -> CoreExpr
mkWildCase CoreExpr
expr (Literal -> Type
literalType Literal
lit) Type
intPrimTy
[(AltCon
DEFAULT, [], CoreExpr
val_if_neq),
(Literal -> AltCon
LitAlt Literal
lit, [], CoreExpr
val_if_eq)])
where
val_if_eq :: CoreExpr
val_if_eq | Bool
is_eq = DynFlags -> CoreExpr
trueValInt DynFlags
dflags
| Bool
otherwise = DynFlags -> CoreExpr
falseValInt DynFlags
dflags
val_if_neq :: CoreExpr
val_if_neq | Bool
is_eq = DynFlags -> CoreExpr
falseValInt DynFlags
dflags
| Bool
otherwise = DynFlags -> CoreExpr
trueValInt DynFlags
dflags
boundsCmp :: Comparison -> RuleM CoreExpr
boundsCmp :: Comparison -> RuleM CoreExpr
boundsCmp Comparison
op = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[CoreExpr
a, CoreExpr
b] <- RuleM [CoreExpr]
getArgs
Maybe CoreExpr -> RuleM CoreExpr
forall a. Maybe a -> RuleM a
liftMaybe (Maybe CoreExpr -> RuleM CoreExpr)
-> Maybe CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Comparison -> CoreExpr -> CoreExpr -> Maybe CoreExpr
mkRuleFn DynFlags
dflags Comparison
op CoreExpr
a CoreExpr
b
data Comparison = Gt | Ge | Lt | Le
mkRuleFn :: DynFlags -> Comparison -> CoreExpr -> CoreExpr -> Maybe CoreExpr
mkRuleFn :: DynFlags -> Comparison -> CoreExpr -> CoreExpr -> Maybe CoreExpr
mkRuleFn DynFlags
dflags Comparison
Gt (Lit Literal
lit) CoreExpr
_ | DynFlags -> Literal -> Bool
isMinBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
falseValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Le (Lit Literal
lit) CoreExpr
_ | DynFlags -> Literal -> Bool
isMinBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
trueValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Ge CoreExpr
_ (Lit Literal
lit) | DynFlags -> Literal -> Bool
isMinBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
trueValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Lt CoreExpr
_ (Lit Literal
lit) | DynFlags -> Literal -> Bool
isMinBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
falseValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Ge (Lit Literal
lit) CoreExpr
_ | DynFlags -> Literal -> Bool
isMaxBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
trueValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Lt (Lit Literal
lit) CoreExpr
_ | DynFlags -> Literal -> Bool
isMaxBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
falseValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Gt CoreExpr
_ (Lit Literal
lit) | DynFlags -> Literal -> Bool
isMaxBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
falseValInt DynFlags
dflags
mkRuleFn DynFlags
dflags Comparison
Le CoreExpr
_ (Lit Literal
lit) | DynFlags -> Literal -> Bool
isMaxBound DynFlags
dflags Literal
lit = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreExpr
trueValInt DynFlags
dflags
mkRuleFn DynFlags
_ Comparison
_ CoreExpr
_ CoreExpr
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
isMinBound :: DynFlags -> Literal -> Bool
isMinBound :: DynFlags -> Literal -> Bool
isMinBound DynFlags
_ (LitChar Char
c) = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
forall a. Bounded a => a
minBound
isMinBound DynFlags
dflags (LitNumber LitNumType
nt Integer
i Type
_) = case LitNumType
nt of
LitNumType
LitNumInt -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Integer
tARGET_MIN_INT DynFlags
dflags
LitNumType
LitNumInt64 -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Int64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Int64
forall a. Bounded a => a
minBound :: Int64)
LitNumType
LitNumWord -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
LitNumType
LitNumWord64 -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
LitNumType
LitNumNatural -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
LitNumType
LitNumInteger -> Bool
False
isMinBound DynFlags
_ Literal
_ = Bool
False
isMaxBound :: DynFlags -> Literal -> Bool
isMaxBound :: DynFlags -> Literal -> Bool
isMaxBound DynFlags
_ (LitChar Char
c) = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
forall a. Bounded a => a
maxBound
isMaxBound DynFlags
dflags (LitNumber LitNumType
nt Integer
i Type
_) = case LitNumType
nt of
LitNumType
LitNumInt -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Integer
tARGET_MAX_INT DynFlags
dflags
LitNumType
LitNumInt64 -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Int64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Int64
forall a. Bounded a => a
maxBound :: Int64)
LitNumType
LitNumWord -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Integer
tARGET_MAX_WORD DynFlags
dflags
LitNumType
LitNumWord64 -> Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word64
forall a. Bounded a => a
maxBound :: Word64)
LitNumType
LitNumNatural -> Bool
False
LitNumType
LitNumInteger -> Bool
False
isMaxBound DynFlags
_ Literal
_ = Bool
False
intResult :: DynFlags -> Integer -> Maybe CoreExpr
intResult :: DynFlags -> Integer -> Maybe CoreExpr
intResult DynFlags
dflags Integer
result = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> Integer -> CoreExpr
intResult' DynFlags
dflags Integer
result)
intResult' :: DynFlags -> Integer -> CoreExpr
intResult' :: DynFlags -> Integer -> CoreExpr
intResult' DynFlags
dflags Integer
result = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitIntWrap DynFlags
dflags Integer
result)
intCResult :: DynFlags -> Integer -> Maybe CoreExpr
intCResult :: DynFlags -> Integer -> Maybe CoreExpr
intCResult DynFlags
dflags Integer
result = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just ([CoreExpr] -> CoreExpr
mkPair [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit, Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
c])
where
mkPair :: [CoreExpr] -> CoreExpr
mkPair = [Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [Type
intPrimTy, Type
intPrimTy]
(Literal
lit, Bool
b) = DynFlags -> Integer -> (Literal, Bool)
mkLitIntWrapC DynFlags
dflags Integer
result
c :: Literal
c = if Bool
b then DynFlags -> Literal
onei DynFlags
dflags else DynFlags -> Literal
zeroi DynFlags
dflags
wordResult :: DynFlags -> Integer -> Maybe CoreExpr
wordResult :: DynFlags -> Integer -> Maybe CoreExpr
wordResult DynFlags
dflags Integer
result = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> Integer -> CoreExpr
wordResult' DynFlags
dflags Integer
result)
wordResult' :: DynFlags -> Integer -> CoreExpr
wordResult' :: DynFlags -> Integer -> CoreExpr
wordResult' DynFlags
dflags Integer
result = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitWordWrap DynFlags
dflags Integer
result)
wordCResult :: DynFlags -> Integer -> Maybe CoreExpr
wordCResult :: DynFlags -> Integer -> Maybe CoreExpr
wordCResult DynFlags
dflags Integer
result = CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just ([CoreExpr] -> CoreExpr
mkPair [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit, Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
c])
where
mkPair :: [CoreExpr] -> CoreExpr
mkPair = [Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [Type
wordPrimTy, Type
intPrimTy]
(Literal
lit, Bool
b) = DynFlags -> Integer -> (Literal, Bool)
mkLitWordWrapC DynFlags
dflags Integer
result
c :: Literal
c = if Bool
b then DynFlags -> Literal
onei DynFlags
dflags else DynFlags -> Literal
zeroi DynFlags
dflags
inversePrimOp :: PrimOp -> RuleM CoreExpr
inversePrimOp :: PrimOp -> RuleM CoreExpr
inversePrimOp PrimOp
primop = do
[Var CoreBndr
primop_id `App` CoreExpr
e] <- RuleM [CoreExpr]
getArgs
PrimOp -> CoreBndr -> RuleM ()
matchPrimOpId PrimOp
primop CoreBndr
primop_id
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e
subsumesPrimOp :: PrimOp -> PrimOp -> RuleM CoreExpr
PrimOp
this subsumesPrimOp :: PrimOp -> PrimOp -> RuleM CoreExpr
`subsumesPrimOp` PrimOp
that = do
[Var CoreBndr
primop_id `App` CoreExpr
e] <- RuleM [CoreExpr]
getArgs
PrimOp -> CoreBndr -> RuleM ()
matchPrimOpId PrimOp
that CoreBndr
primop_id
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (PrimOp -> CoreBndr
mkPrimOpId PrimOp
this) CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
e)
subsumedByPrimOp :: PrimOp -> RuleM CoreExpr
subsumedByPrimOp :: PrimOp -> RuleM CoreExpr
subsumedByPrimOp PrimOp
primop = do
[e :: CoreExpr
e@(Var CoreBndr
primop_id `App` CoreExpr
_)] <- RuleM [CoreExpr]
getArgs
PrimOp -> CoreBndr -> RuleM ()
matchPrimOpId PrimOp
primop CoreBndr
primop_id
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e
idempotent :: RuleM CoreExpr
idempotent :: RuleM CoreExpr
idempotent = do [CoreExpr
e1, CoreExpr
e2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
cheapEqExpr CoreExpr
e1 CoreExpr
e2
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e1
mkBasicRule :: Name -> Int -> RuleM CoreExpr -> CoreRule
mkBasicRule :: Name -> Int -> RuleM CoreExpr -> CoreRule
mkBasicRule Name
op_name Int
n_args RuleM CoreExpr
rm
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = OccName -> RuleName
occNameFS (Name -> OccName
nameOccName Name
op_name),
ru_fn :: Name
ru_fn = Name
op_name,
ru_nargs :: Int
ru_nargs = Int
n_args,
ru_try :: RuleFun
ru_try = \ DynFlags
dflags InScopeEnv
in_scope CoreBndr
_ -> RuleM CoreExpr
-> DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe CoreExpr
forall r.
RuleM r -> DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r
runRuleM RuleM CoreExpr
rm DynFlags
dflags InScopeEnv
in_scope }
newtype RuleM r = RuleM
{ RuleM r -> DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r
runRuleM :: DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r }
deriving (a -> RuleM b -> RuleM a
(a -> b) -> RuleM a -> RuleM b
(forall a b. (a -> b) -> RuleM a -> RuleM b)
-> (forall a b. a -> RuleM b -> RuleM a) -> Functor RuleM
forall a b. a -> RuleM b -> RuleM a
forall a b. (a -> b) -> RuleM a -> RuleM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> RuleM b -> RuleM a
$c<$ :: forall a b. a -> RuleM b -> RuleM a
fmap :: (a -> b) -> RuleM a -> RuleM b
$cfmap :: forall a b. (a -> b) -> RuleM a -> RuleM b
Functor)
instance Applicative RuleM where
pure :: a -> RuleM a
pure a
x = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ InScopeEnv
_ [CoreExpr]
_ -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
<*> :: RuleM (a -> b) -> RuleM a -> RuleM b
(<*>) = RuleM (a -> b) -> RuleM a -> RuleM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad RuleM where
RuleM DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a
f >>= :: RuleM a -> (a -> RuleM b) -> RuleM b
>>= a -> RuleM b
g = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe b) -> RuleM b
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe b) -> RuleM b)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe b) -> RuleM b
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags InScopeEnv
iu [CoreExpr]
e -> case DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a
f DynFlags
dflags InScopeEnv
iu [CoreExpr]
e of
Maybe a
Nothing -> Maybe b
forall a. Maybe a
Nothing
Just a
r -> RuleM b -> DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe b
forall r.
RuleM r -> DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r
runRuleM (a -> RuleM b
g a
r) DynFlags
dflags InScopeEnv
iu [CoreExpr]
e
#if !MIN_VERSION_base(4,13,0)
fail = MonadFail.fail
#endif
instance MonadFail.MonadFail RuleM where
fail :: String -> RuleM a
fail String
_ = RuleM a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
instance Alternative RuleM where
empty :: RuleM a
empty = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ InScopeEnv
_ [CoreExpr]
_ -> Maybe a
forall a. Maybe a
Nothing
RuleM DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a
f1 <|> :: RuleM a -> RuleM a -> RuleM a
<|> RuleM DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a
f2 = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a) -> RuleM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags InScopeEnv
iu [CoreExpr]
args ->
DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a
f1 DynFlags
dflags InScopeEnv
iu [CoreExpr]
args Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe a
f2 DynFlags
dflags InScopeEnv
iu [CoreExpr]
args
instance MonadPlus RuleM
instance HasDynFlags RuleM where
getDynFlags :: RuleM DynFlags
getDynFlags = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe DynFlags)
-> RuleM DynFlags
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe DynFlags)
-> RuleM DynFlags)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe DynFlags)
-> RuleM DynFlags
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags InScopeEnv
_ [CoreExpr]
_ -> DynFlags -> Maybe DynFlags
forall a. a -> Maybe a
Just DynFlags
dflags
liftMaybe :: Maybe a -> RuleM a
liftMaybe :: Maybe a -> RuleM a
liftMaybe Maybe a
Nothing = RuleM a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
liftMaybe (Just a
x) = a -> RuleM a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
liftLit :: (Literal -> Literal) -> RuleM CoreExpr
liftLit :: (Literal -> Literal) -> RuleM CoreExpr
liftLit Literal -> Literal
f = (DynFlags -> Literal -> Literal) -> RuleM CoreExpr
liftLitDynFlags ((Literal -> Literal) -> DynFlags -> Literal -> Literal
forall a b. a -> b -> a
const Literal -> Literal
f)
liftLitDynFlags :: (DynFlags -> Literal -> Literal) -> RuleM CoreExpr
liftLitDynFlags :: (DynFlags -> Literal -> Literal) -> RuleM CoreExpr
liftLitDynFlags DynFlags -> Literal -> Literal
f = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[Lit Literal
lit] <- RuleM [CoreExpr]
getArgs
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Literal -> Literal
f DynFlags
dflags Literal
lit)
removeOp32 :: RuleM CoreExpr
removeOp32 :: RuleM CoreExpr
removeOp32 = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
case Platform -> PlatformWordSize
platformWordSize (DynFlags -> Platform
targetPlatform DynFlags
dflags) of
PlatformWordSize
PW4 -> do
[CoreExpr
e] <- RuleM [CoreExpr]
getArgs
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e
PlatformWordSize
PW8 ->
RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a
mzero
getArgs :: RuleM [CoreExpr]
getArgs :: RuleM [CoreExpr]
getArgs = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe [CoreExpr])
-> RuleM [CoreExpr]
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe [CoreExpr])
-> RuleM [CoreExpr])
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe [CoreExpr])
-> RuleM [CoreExpr]
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ InScopeEnv
_ [CoreExpr]
args -> [CoreExpr] -> Maybe [CoreExpr]
forall a. a -> Maybe a
Just [CoreExpr]
args
getInScopeEnv :: RuleM InScopeEnv
getInScopeEnv :: RuleM InScopeEnv
getInScopeEnv = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe InScopeEnv)
-> RuleM InScopeEnv
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe InScopeEnv)
-> RuleM InScopeEnv)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe InScopeEnv)
-> RuleM InScopeEnv
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ InScopeEnv
iu [CoreExpr]
_ -> InScopeEnv -> Maybe InScopeEnv
forall a. a -> Maybe a
Just InScopeEnv
iu
getLiteral :: Int -> RuleM Literal
getLiteral :: Int -> RuleM Literal
getLiteral Int
n = (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe Literal)
-> RuleM Literal
forall r.
(DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe r) -> RuleM r
RuleM ((DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe Literal)
-> RuleM Literal)
-> (DynFlags -> InScopeEnv -> [CoreExpr] -> Maybe Literal)
-> RuleM Literal
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ InScopeEnv
_ [CoreExpr]
exprs -> case Int -> [CoreExpr] -> [CoreExpr]
forall a. Int -> [a] -> [a]
drop Int
n [CoreExpr]
exprs of
(Lit Literal
l:[CoreExpr]
_) -> Literal -> Maybe Literal
forall a. a -> Maybe a
Just Literal
l
[CoreExpr]
_ -> Maybe Literal
forall a. Maybe a
Nothing
unaryLit :: (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit :: (DynFlags -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
unaryLit DynFlags -> Literal -> Maybe CoreExpr
op = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[Lit Literal
l] <- RuleM [CoreExpr]
getArgs
Maybe CoreExpr -> RuleM CoreExpr
forall a. Maybe a -> RuleM a
liftMaybe (Maybe CoreExpr -> RuleM CoreExpr)
-> Maybe CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Literal -> Maybe CoreExpr
op DynFlags
dflags (DynFlags -> Literal -> Literal
convFloating DynFlags
dflags Literal
l)
binaryLit :: (DynFlags -> Literal -> Literal -> Maybe CoreExpr) -> RuleM CoreExpr
binaryLit :: (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit DynFlags -> Literal -> Literal -> Maybe CoreExpr
op = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[Lit Literal
l1, Lit Literal
l2] <- RuleM [CoreExpr]
getArgs
Maybe CoreExpr -> RuleM CoreExpr
forall a. Maybe a -> RuleM a
liftMaybe (Maybe CoreExpr -> RuleM CoreExpr)
-> Maybe CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Literal -> Literal -> Maybe CoreExpr
op DynFlags
dflags (DynFlags -> Literal -> Literal
convFloating DynFlags
dflags Literal
l1) (DynFlags -> Literal -> Literal
convFloating DynFlags
dflags Literal
l2)
binaryCmpLit :: (forall a . Ord a => a -> a -> Bool) -> RuleM CoreExpr
binaryCmpLit :: (forall a. Ord a => a -> a -> Bool) -> RuleM CoreExpr
binaryCmpLit forall a. Ord a => a -> a -> Bool
op = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
(DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit (\DynFlags
_ -> DynFlags
-> (forall a. Ord a => a -> a -> Bool)
-> Literal
-> Literal
-> Maybe CoreExpr
cmpOp DynFlags
dflags forall a. Ord a => a -> a -> Bool
op)
leftIdentity :: Literal -> RuleM CoreExpr
leftIdentity :: Literal -> RuleM CoreExpr
leftIdentity Literal
id_lit = (DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityDynFlags (Literal -> DynFlags -> Literal
forall a b. a -> b -> a
const Literal
id_lit)
rightIdentity :: Literal -> RuleM CoreExpr
rightIdentity :: Literal -> RuleM CoreExpr
rightIdentity Literal
id_lit = (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags (Literal -> DynFlags -> Literal
forall a b. a -> b -> a
const Literal
id_lit)
identity :: Literal -> RuleM CoreExpr
identity :: Literal -> RuleM CoreExpr
identity Literal
lit = Literal -> RuleM CoreExpr
leftIdentity Literal
lit RuleM CoreExpr -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Literal -> RuleM CoreExpr
rightIdentity Literal
lit
leftIdentityDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityDynFlags DynFlags -> Literal
id_lit = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[Lit Literal
l1, CoreExpr
e2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Literal
l1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
id_lit DynFlags
dflags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e2
leftIdentityCDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityCDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityCDynFlags DynFlags -> Literal
id_lit = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[Lit Literal
l1, CoreExpr
e2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Literal
l1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
id_lit DynFlags
dflags
let no_c :: Expr b
no_c = Literal -> Expr b
forall b. Literal -> Expr b
Lit (DynFlags -> Literal
zeroi DynFlags
dflags)
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [CoreExpr -> Type
exprType CoreExpr
e2, Type
intPrimTy] [CoreExpr
e2, CoreExpr
forall b. Expr b
no_c])
rightIdentityDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
id_lit = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[CoreExpr
e1, Lit Literal
l2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Literal
l2 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
id_lit DynFlags
dflags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e1
rightIdentityCDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityCDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityCDynFlags DynFlags -> Literal
id_lit = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[CoreExpr
e1, Lit Literal
l2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Literal
l2 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
id_lit DynFlags
dflags
let no_c :: Expr b
no_c = Literal -> Expr b
forall b. Literal -> Expr b
Lit (DynFlags -> Literal
zeroi DynFlags
dflags)
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [CoreExpr -> Type
exprType CoreExpr
e1, Type
intPrimTy] [CoreExpr
e1, CoreExpr
forall b. Expr b
no_c])
identityDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
identityDynFlags DynFlags -> Literal
lit =
(DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityDynFlags DynFlags -> Literal
lit RuleM CoreExpr -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityDynFlags DynFlags -> Literal
lit
identityCDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
identityCDynFlags :: (DynFlags -> Literal) -> RuleM CoreExpr
identityCDynFlags DynFlags -> Literal
lit =
(DynFlags -> Literal) -> RuleM CoreExpr
leftIdentityCDynFlags DynFlags -> Literal
lit RuleM CoreExpr -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (DynFlags -> Literal) -> RuleM CoreExpr
rightIdentityCDynFlags DynFlags -> Literal
lit
leftZero :: (DynFlags -> Literal) -> RuleM CoreExpr
leftZero :: (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
zero = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[Lit Literal
l1, CoreExpr
_] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Literal
l1 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
zero DynFlags
dflags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l1
rightZero :: (DynFlags -> Literal) -> RuleM CoreExpr
rightZero :: (DynFlags -> Literal) -> RuleM CoreExpr
rightZero DynFlags -> Literal
zero = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[CoreExpr
_, Lit Literal
l2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Literal
l2 Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== DynFlags -> Literal
zero DynFlags
dflags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l2
zeroElem :: (DynFlags -> Literal) -> RuleM CoreExpr
zeroElem :: (DynFlags -> Literal) -> RuleM CoreExpr
zeroElem DynFlags -> Literal
lit = (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
lit RuleM CoreExpr -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (DynFlags -> Literal) -> RuleM CoreExpr
rightZero DynFlags -> Literal
lit
equalArgs :: RuleM ()
equalArgs :: RuleM ()
equalArgs = do
[CoreExpr
e1, CoreExpr
e2] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ CoreExpr
e1 CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
e2
nonZeroLit :: Int -> RuleM ()
nonZeroLit :: Int -> RuleM ()
nonZeroLit Int
n = Int -> RuleM Literal
getLiteral Int
n RuleM Literal -> (Literal -> RuleM ()) -> RuleM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> (Literal -> Bool) -> Literal -> RuleM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Bool) -> (Literal -> Bool) -> Literal -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Literal -> Bool
isZeroLit
convFloating :: DynFlags -> Literal -> Literal
convFloating :: DynFlags -> Literal -> Literal
convFloating DynFlags
dflags (LitFloat Rational
f) | Bool -> Bool
not (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_ExcessPrecision DynFlags
dflags) =
Rational -> Literal
LitFloat (Float -> Rational
forall a. Real a => a -> Rational
toRational (Rational -> Float
forall a. Fractional a => Rational -> a
fromRational Rational
f :: Float ))
convFloating DynFlags
dflags (LitDouble Rational
d) | Bool -> Bool
not (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_ExcessPrecision DynFlags
dflags) =
Rational -> Literal
LitDouble (Double -> Rational
forall a. Real a => a -> Rational
toRational (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
d :: Double))
convFloating DynFlags
_ Literal
l = Literal
l
guardFloatDiv :: RuleM ()
guardFloatDiv :: RuleM ()
guardFloatDiv = do
[Lit (LitFloat Rational
f1), Lit (LitFloat Rational
f2)] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ (Rational
f1 Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/=Rational
0 Bool -> Bool -> Bool
|| Rational
f2 Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0)
Bool -> Bool -> Bool
&& Rational
f2 Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0
guardDoubleDiv :: RuleM ()
guardDoubleDiv :: RuleM ()
guardDoubleDiv = do
[Lit (LitDouble Rational
d1), Lit (LitDouble Rational
d2)] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ (Rational
d1 Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/=Rational
0 Bool -> Bool -> Bool
|| Rational
d2 Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0)
Bool -> Bool -> Bool
&& Rational
d2 Rational -> Rational -> Bool
forall a. Eq a => a -> a -> Bool
/= Rational
0
strengthReduction :: Literal -> PrimOp -> RuleM CoreExpr
strengthReduction :: Literal -> PrimOp -> RuleM CoreExpr
strengthReduction Literal
two_lit PrimOp
add_op = do
CoreExpr
arg <- [RuleM CoreExpr] -> RuleM CoreExpr
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ do [CoreExpr
arg, Lit Literal
mult_lit] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Literal
mult_lit Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
two_lit)
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
arg
, do [Lit Literal
mult_lit, CoreExpr
arg] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Literal
mult_lit Literal -> Literal -> Bool
forall a. Eq a => a -> a -> Bool
== Literal
two_lit)
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
arg ]
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (PrimOp -> CoreBndr
mkPrimOpId PrimOp
add_op) CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
arg CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
arg
trueValInt, falseValInt :: DynFlags -> Expr CoreBndr
trueValInt :: DynFlags -> CoreExpr
trueValInt DynFlags
dflags = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Literal -> CoreExpr) -> Literal -> CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Literal
onei DynFlags
dflags
falseValInt :: DynFlags -> CoreExpr
falseValInt DynFlags
dflags = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Literal -> CoreExpr) -> Literal -> CoreExpr
forall a b. (a -> b) -> a -> b
$ DynFlags -> Literal
zeroi DynFlags
dflags
trueValBool, falseValBool :: Expr CoreBndr
trueValBool :: CoreExpr
trueValBool = CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
trueDataConId
falseValBool :: CoreExpr
falseValBool = CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
falseDataConId
ltVal, eqVal, gtVal :: Expr CoreBndr
ltVal :: CoreExpr
ltVal = CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
ordLTDataConId
eqVal :: CoreExpr
eqVal = CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
ordEQDataConId
gtVal :: CoreExpr
gtVal = CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
ordGTDataConId
mkIntVal :: DynFlags -> Integer -> Expr CoreBndr
mkIntVal :: DynFlags -> Integer -> CoreExpr
mkIntVal DynFlags
dflags Integer
i = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags Integer
i)
mkFloatVal :: DynFlags -> Rational -> Expr CoreBndr
mkFloatVal :: DynFlags -> Rational -> CoreExpr
mkFloatVal DynFlags
dflags Rational
f = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Literal -> Literal
convFloating DynFlags
dflags (Rational -> Literal
LitFloat Rational
f))
mkDoubleVal :: DynFlags -> Rational -> Expr CoreBndr
mkDoubleVal :: DynFlags -> Rational -> CoreExpr
mkDoubleVal DynFlags
dflags Rational
d = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Literal -> Literal
convFloating DynFlags
dflags (Rational -> Literal
LitDouble Rational
d))
matchPrimOpId :: PrimOp -> Id -> RuleM ()
matchPrimOpId :: PrimOp -> CoreBndr -> RuleM ()
matchPrimOpId PrimOp
op CoreBndr
id = do
PrimOp
op' <- Maybe PrimOp -> RuleM PrimOp
forall a. Maybe a -> RuleM a
liftMaybe (Maybe PrimOp -> RuleM PrimOp) -> Maybe PrimOp -> RuleM PrimOp
forall a b. (a -> b) -> a -> b
$ CoreBndr -> Maybe PrimOp
isPrimOpId_maybe CoreBndr
id
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ PrimOp
op PrimOp -> PrimOp -> Bool
forall a. Eq a => a -> a -> Bool
== PrimOp
op'
tagToEnumRule :: RuleM CoreExpr
tagToEnumRule :: RuleM CoreExpr
tagToEnumRule = do
[Type Type
ty, Lit (LitNumber LitNumType
LitNumInt Integer
i Type
_)] <- RuleM [CoreExpr]
getArgs
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty of
Just (TyCon
tycon, [Type]
tc_args) | TyCon -> Bool
isEnumerationTyCon TyCon
tycon -> do
let tag :: Int
tag = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
i
correct_tag :: DataCon -> Bool
correct_tag DataCon
dc = (DataCon -> Int
dataConTagZ DataCon
dc) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
tag
(DataCon
dc:[DataCon]
rest) <- [DataCon] -> RuleM [DataCon]
forall (m :: * -> *) a. Monad m => a -> m a
return ([DataCon] -> RuleM [DataCon]) -> [DataCon] -> RuleM [DataCon]
forall a b. (a -> b) -> a -> b
$ (DataCon -> Bool) -> [DataCon] -> [DataCon]
forall a. (a -> Bool) -> [a] -> [a]
filter DataCon -> Bool
correct_tag (TyCon -> Maybe [DataCon]
tyConDataCons_maybe TyCon
tycon Maybe [DataCon] -> [DataCon] -> [DataCon]
forall a. Maybe a -> a -> a
`orElse` [])
ASSERT(null rest) return ()
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> [Type] -> CoreExpr
forall b. Expr b -> [Type] -> Expr b
mkTyApps (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (DataCon -> CoreBndr
dataConWorkId DataCon
dc)) [Type]
tc_args
Maybe (TyCon, [Type])
_ -> WARN( True, text "tagToEnum# on non-enumeration type" <+> ppr ty )
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreBndr -> Type -> String -> CoreExpr
mkRuntimeErrorApp CoreBndr
rUNTIME_ERROR_ID Type
ty String
"tagToEnum# on non-enumeration type"
dataToTagRule :: RuleM CoreExpr
dataToTagRule :: RuleM CoreExpr
dataToTagRule = RuleM CoreExpr
a RuleM CoreExpr -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` RuleM CoreExpr
b
where
a :: RuleM CoreExpr
a = do
[Type Type
ty1, Var CoreBndr
tag_to_enum `App` Type Type
ty2 `App` CoreExpr
tag] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ CoreBndr
tag_to_enum CoreBndr -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
tagToEnumKey
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ Type
ty1 Type -> Type -> Bool
`eqType` Type
ty2
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
tag
b :: RuleM CoreExpr
b = do
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
[CoreExpr
_, CoreExpr
val_arg] <- RuleM [CoreExpr]
getArgs
InScopeEnv
in_scope <- RuleM InScopeEnv
getInScopeEnv
(InScopeSet
_,[FloatBind]
floats, DataCon
dc,[Type]
_,[CoreExpr]
_) <- Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
-> RuleM (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
forall a. Maybe a -> RuleM a
liftMaybe (Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
-> RuleM (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr]))
-> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
-> RuleM (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
forall a b. (a -> b) -> a -> b
$ InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
exprIsConApp_maybe InScopeEnv
in_scope CoreExpr
val_arg
ASSERT( not (isNewTyCon (dataConTyCon dc)) ) return ()
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ [FloatBind] -> CoreExpr -> CoreExpr
wrapFloats [FloatBind]
floats (DynFlags -> Integer -> CoreExpr
mkIntVal DynFlags
dflags (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (DataCon -> Int
dataConTagZ DataCon
dc)))
seqRule :: RuleM CoreExpr
seqRule :: RuleM CoreExpr
seqRule = do
[Type Type
ty_a, Type Type
_ty_s, CoreExpr
a, CoreExpr
s] <- RuleM [CoreExpr]
getArgs
Bool -> RuleM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> RuleM ()) -> Bool -> RuleM ()
forall a b. (a -> b) -> a -> b
$ CoreExpr -> Bool
exprIsHNF CoreExpr
a
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ [Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [CoreExpr -> Type
exprType CoreExpr
s, Type
ty_a] [CoreExpr
s, CoreExpr
a]
sparkRule :: RuleM CoreExpr
sparkRule :: RuleM CoreExpr
sparkRule = RuleM CoreExpr
seqRule
builtinRules :: [CoreRule]
builtinRules :: [CoreRule]
builtinRules
= [BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
"AppendLitString",
ru_fn :: Name
ru_fn = Name
unpackCStringFoldrName,
ru_nargs :: Int
ru_nargs = Int
4, ru_try :: RuleFun
ru_try = RuleFun
match_append_lit },
BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
"EqString", ru_fn :: Name
ru_fn = Name
eqStringName,
ru_nargs :: Int
ru_nargs = Int
2, ru_try :: RuleFun
ru_try = RuleFun
match_eq_string },
BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
"Inline", ru_fn :: Name
ru_fn = Name
inlineIdName,
ru_nargs :: Int
ru_nargs = Int
2, ru_try :: RuleFun
ru_try = \DynFlags
_ InScopeEnv
_ CoreBndr
_ -> [CoreExpr] -> Maybe CoreExpr
match_inline },
BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
"MagicDict", ru_fn :: Name
ru_fn = CoreBndr -> Name
idName CoreBndr
magicDictId,
ru_nargs :: Int
ru_nargs = Int
4, ru_try :: RuleFun
ru_try = \DynFlags
_ InScopeEnv
_ CoreBndr
_ -> [CoreExpr] -> Maybe CoreExpr
match_magicDict },
Name -> Int -> RuleM CoreExpr -> CoreRule
mkBasicRule Name
divIntName Int
2 (RuleM CoreExpr -> CoreRule) -> RuleM CoreExpr -> CoreRule
forall a b. (a -> b) -> a -> b
$ [RuleM CoreExpr] -> RuleM CoreExpr
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
[ Int -> RuleM ()
nonZeroLit Int
1 RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div)
, (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
zeroi
, do
[CoreExpr
arg, Lit (LitNumber LitNumType
LitNumInt Integer
d Type
_)] <- RuleM [CoreExpr]
getArgs
Just Integer
n <- Maybe Integer -> RuleM (Maybe Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Integer -> RuleM (Maybe Integer))
-> Maybe Integer -> RuleM (Maybe Integer)
forall a b. (a -> b) -> a -> b
$ Integer -> Maybe Integer
exactLog2 Integer
d
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (PrimOp -> CoreBndr
mkPrimOpId PrimOp
ISraOp) CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
arg CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` DynFlags -> Integer -> CoreExpr
mkIntVal DynFlags
dflags Integer
n
],
Name -> Int -> RuleM CoreExpr -> CoreRule
mkBasicRule Name
modIntName Int
2 (RuleM CoreExpr -> CoreRule) -> RuleM CoreExpr -> CoreRule
forall a b. (a -> b) -> a -> b
$ [RuleM CoreExpr] -> RuleM CoreExpr
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
[ Int -> RuleM ()
nonZeroLit Int
1 RuleM () -> RuleM CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (DynFlags -> Literal -> Literal -> Maybe CoreExpr)
-> RuleM CoreExpr
binaryLit ((Integer -> Integer -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
forall a b.
(Integral a, Integral b) =>
(a -> b -> Integer)
-> DynFlags -> Literal -> Literal -> Maybe CoreExpr
intOp2 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod)
, (DynFlags -> Literal) -> RuleM CoreExpr
leftZero DynFlags -> Literal
zeroi
, do
[CoreExpr
arg, Lit (LitNumber LitNumType
LitNumInt Integer
d Type
_)] <- RuleM [CoreExpr]
getArgs
Just Integer
_ <- Maybe Integer -> RuleM (Maybe Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Integer -> RuleM (Maybe Integer))
-> Maybe Integer -> RuleM (Maybe Integer)
forall a b. (a -> b) -> a -> b
$ Integer -> Maybe Integer
exactLog2 Integer
d
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (PrimOp -> CoreBndr
mkPrimOpId PrimOp
AndIOp)
CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
arg CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` DynFlags -> Integer -> CoreExpr
mkIntVal DynFlags
dflags (Integer
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
]
]
[CoreRule] -> [CoreRule] -> [CoreRule]
forall a. [a] -> [a] -> [a]
++ [CoreRule]
builtinIntegerRules
[CoreRule] -> [CoreRule] -> [CoreRule]
forall a. [a] -> [a] -> [a]
++ [CoreRule]
builtinNaturalRules
{-# NOINLINE builtinRules #-}
builtinIntegerRules :: [CoreRule]
builtinIntegerRules :: [CoreRule]
builtinIntegerRules =
[String -> Name -> CoreRule
rule_IntToInteger String
"smallInteger" Name
smallIntegerName,
String -> Name -> CoreRule
rule_WordToInteger String
"wordToInteger" Name
wordToIntegerName,
String -> Name -> CoreRule
rule_Int64ToInteger String
"int64ToInteger" Name
int64ToIntegerName,
String -> Name -> CoreRule
rule_Word64ToInteger String
"word64ToInteger" Name
word64ToIntegerName,
String -> Name -> (DynFlags -> Word -> CoreExpr) -> CoreRule
forall a.
Num a =>
String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
"integerToWord" Name
integerToWordName DynFlags -> Word -> CoreExpr
forall b. DynFlags -> Word -> Expr b
mkWordLitWord,
String -> Name -> (DynFlags -> Int -> CoreExpr) -> CoreRule
forall a.
Num a =>
String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
"integerToInt" Name
integerToIntName DynFlags -> Int -> CoreExpr
forall b. DynFlags -> Int -> Expr b
mkIntLitInt,
String -> Name -> (DynFlags -> Word64 -> CoreExpr) -> CoreRule
forall a.
Num a =>
String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
"integerToWord64" Name
integerToWord64Name (\DynFlags
_ -> Word64 -> CoreExpr
forall b. Word64 -> Expr b
mkWord64LitWord64),
String -> Name -> (DynFlags -> Int64 -> CoreExpr) -> CoreRule
forall a.
Num a =>
String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
"integerToInt64" Name
integerToInt64Name (\DynFlags
_ -> Int64 -> CoreExpr
forall b. Int64 -> Expr b
mkInt64LitInt64),
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"plusInteger" Name
plusIntegerName Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+),
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"minusInteger" Name
minusIntegerName (-),
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"timesInteger" Name
timesIntegerName Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*),
String -> Name -> (Integer -> Integer) -> CoreRule
rule_unop String
"negateInteger" Name
negateIntegerName Integer -> Integer
forall a. Num a => a -> a
negate,
String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
"eqInteger#" Name
eqIntegerPrimName Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
(==),
String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
"neqInteger#" Name
neqIntegerPrimName Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
(/=),
String -> Name -> (Integer -> Integer) -> CoreRule
rule_unop String
"absInteger" Name
absIntegerName Integer -> Integer
forall a. Num a => a -> a
abs,
String -> Name -> (Integer -> Integer) -> CoreRule
rule_unop String
"signumInteger" Name
signumIntegerName Integer -> Integer
forall a. Num a => a -> a
signum,
String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
"leInteger#" Name
leIntegerPrimName Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(<=),
String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
"gtInteger#" Name
gtIntegerPrimName Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(>),
String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
"ltInteger#" Name
ltIntegerPrimName Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(<),
String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
"geInteger#" Name
geIntegerPrimName Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(>=),
String -> Name -> (Integer -> Integer -> Ordering) -> CoreRule
rule_binop_Ordering String
"compareInteger" Name
compareIntegerName Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare,
String -> Name -> (Float -> CoreExpr) -> CoreRule
forall a.
RealFloat a =>
String -> Name -> (a -> CoreExpr) -> CoreRule
rule_encodeFloat String
"encodeFloatInteger" Name
encodeFloatIntegerName Float -> CoreExpr
forall b. Float -> Expr b
mkFloatLitFloat,
String -> Name -> (DynFlags -> Float -> CoreExpr) -> CoreRule
forall a.
Num a =>
String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
"floatFromInteger" Name
floatFromIntegerName (\DynFlags
_ -> Float -> CoreExpr
forall b. Float -> Expr b
mkFloatLitFloat),
String -> Name -> (Double -> CoreExpr) -> CoreRule
forall a.
RealFloat a =>
String -> Name -> (a -> CoreExpr) -> CoreRule
rule_encodeFloat String
"encodeDoubleInteger" Name
encodeDoubleIntegerName Double -> CoreExpr
forall b. Double -> Expr b
mkDoubleLitDouble,
String -> Name -> CoreRule
rule_decodeDouble String
"decodeDoubleInteger" Name
decodeDoubleIntegerName,
String -> Name -> (DynFlags -> Double -> CoreExpr) -> CoreRule
forall a.
Num a =>
String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
"doubleFromInteger" Name
doubleFromIntegerName (\DynFlags
_ -> Double -> CoreExpr
forall b. Double -> Expr b
mkDoubleLitDouble),
String -> Name -> (Float -> CoreExpr) -> CoreRule
forall a.
RealFloat a =>
String -> Name -> (a -> CoreExpr) -> CoreRule
rule_rationalTo String
"rationalToFloat" Name
rationalToFloatName Float -> CoreExpr
mkFloatExpr,
String -> Name -> (Double -> CoreExpr) -> CoreRule
forall a.
RealFloat a =>
String -> Name -> (a -> CoreExpr) -> CoreRule
rule_rationalTo String
"rationalToDouble" Name
rationalToDoubleName Double -> CoreExpr
mkDoubleExpr,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"gcdInteger" Name
gcdIntegerName Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
gcd,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"lcmInteger" Name
lcmIntegerName Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
lcm,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"andInteger" Name
andIntegerName Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
(.&.),
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"orInteger" Name
orIntegerName Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
(.|.),
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"xorInteger" Name
xorIntegerName Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor,
String -> Name -> (Integer -> Integer) -> CoreRule
rule_unop String
"complementInteger" Name
complementIntegerName Integer -> Integer
forall a. Bits a => a -> a
complement,
String -> Name -> (Integer -> Int -> Integer) -> CoreRule
rule_shift_op String
"shiftLInteger" Name
shiftLIntegerName Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL,
String -> Name -> (Integer -> Int -> Integer) -> CoreRule
rule_shift_op String
"shiftRInteger" Name
shiftRIntegerName Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR,
String -> Name -> CoreRule
rule_bitInteger String
"bitInteger" Name
bitIntegerName,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_divop_one String
"quotInteger" Name
quotIntegerName Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
quot,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_divop_one String
"remInteger" Name
remIntegerName Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
rem,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_divop_one String
"divInteger" Name
divIntegerName Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div,
String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_divop_one String
"modInteger" Name
modIntegerName Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod,
String
-> Name -> (Integer -> Integer -> (Integer, Integer)) -> CoreRule
rule_divop_both String
"divModInteger" Name
divModIntegerName Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
divMod,
String
-> Name -> (Integer -> Integer -> (Integer, Integer)) -> CoreRule
rule_divop_both String
"quotRemInteger" Name
quotRemIntegerName Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
quotRem,
String -> Name -> Name -> CoreRule
rule_XToIntegerToX String
"smallIntegerToInt" Name
integerToIntName Name
smallIntegerName,
String -> Name -> Name -> CoreRule
rule_XToIntegerToX String
"wordToIntegerToWord" Name
integerToWordName Name
wordToIntegerName,
String -> Name -> Name -> CoreRule
rule_XToIntegerToX String
"int64ToIntegerToInt64" Name
integerToInt64Name Name
int64ToIntegerName,
String -> Name -> Name -> CoreRule
rule_XToIntegerToX String
"word64ToIntegerToWord64" Name
integerToWord64Name Name
word64ToIntegerName,
String -> Name -> PrimOp -> CoreRule
rule_smallIntegerTo String
"smallIntegerToWord" Name
integerToWordName PrimOp
Int2WordOp,
String -> Name -> PrimOp -> CoreRule
rule_smallIntegerTo String
"smallIntegerToFloat" Name
floatFromIntegerName PrimOp
Int2FloatOp,
String -> Name -> PrimOp -> CoreRule
rule_smallIntegerTo String
"smallIntegerToDouble" Name
doubleFromIntegerName PrimOp
Int2DoubleOp
]
where rule_convert :: String -> Name -> (DynFlags -> a -> CoreExpr) -> CoreRule
rule_convert String
str Name
name DynFlags -> a -> CoreExpr
convert
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = (DynFlags -> a -> CoreExpr) -> RuleFun
forall a. Num a => (DynFlags -> a -> CoreExpr) -> RuleFun
match_Integer_convert DynFlags -> a -> CoreExpr
convert }
rule_IntToInteger :: String -> Name -> CoreRule
rule_IntToInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_IntToInteger }
rule_WordToInteger :: String -> Name -> CoreRule
rule_WordToInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_WordToInteger }
rule_Int64ToInteger :: String -> Name -> CoreRule
rule_Int64ToInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_Int64ToInteger }
rule_Word64ToInteger :: String -> Name -> CoreRule
rule_Word64ToInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_Word64ToInteger }
rule_unop :: String -> Name -> (Integer -> Integer) -> CoreRule
rule_unop String
str Name
name Integer -> Integer
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = (Integer -> Integer) -> RuleFun
match_Integer_unop Integer -> Integer
op }
rule_bitInteger :: String -> Name -> CoreRule
rule_bitInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_bitInteger }
rule_binop :: String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
str Name
name Integer -> Integer -> Integer
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> Integer) -> RuleFun
match_Integer_binop Integer -> Integer -> Integer
op }
rule_divop_both :: String
-> Name -> (Integer -> Integer -> (Integer, Integer)) -> CoreRule
rule_divop_both String
str Name
name Integer -> Integer -> (Integer, Integer)
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> (Integer, Integer)) -> RuleFun
match_Integer_divop_both Integer -> Integer -> (Integer, Integer)
op }
rule_divop_one :: String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_divop_one String
str Name
name Integer -> Integer -> Integer
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> Integer) -> RuleFun
match_Integer_divop_one Integer -> Integer -> Integer
op }
rule_shift_op :: String -> Name -> (Integer -> Int -> Integer) -> CoreRule
rule_shift_op String
str Name
name Integer -> Int -> Integer
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Int -> Integer) -> RuleFun
match_Integer_shift_op Integer -> Int -> Integer
op }
rule_binop_Prim :: String -> Name -> (Integer -> Integer -> Bool) -> CoreRule
rule_binop_Prim String
str Name
name Integer -> Integer -> Bool
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> Bool) -> RuleFun
match_Integer_binop_Prim Integer -> Integer -> Bool
op }
rule_binop_Ordering :: String -> Name -> (Integer -> Integer -> Ordering) -> CoreRule
rule_binop_Ordering String
str Name
name Integer -> Integer -> Ordering
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> Ordering) -> RuleFun
match_Integer_binop_Ordering Integer -> Integer -> Ordering
op }
rule_encodeFloat :: String -> Name -> (a -> CoreExpr) -> CoreRule
rule_encodeFloat String
str Name
name a -> CoreExpr
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (a -> CoreExpr) -> RuleFun
forall a. RealFloat a => (a -> CoreExpr) -> RuleFun
match_Integer_Int_encodeFloat a -> CoreExpr
op }
rule_decodeDouble :: String -> Name -> CoreRule
rule_decodeDouble String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_decodeDouble }
rule_XToIntegerToX :: String -> Name -> Name -> CoreRule
rule_XToIntegerToX String
str Name
name Name
toIntegerName
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = Name -> RuleFun
match_XToIntegerToX Name
toIntegerName }
rule_smallIntegerTo :: String -> Name -> PrimOp -> CoreRule
rule_smallIntegerTo String
str Name
name PrimOp
primOp
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = PrimOp -> RuleFun
match_smallIntegerTo PrimOp
primOp }
rule_rationalTo :: String -> Name -> (a -> CoreExpr) -> CoreRule
rule_rationalTo String
str Name
name a -> CoreExpr
mkLit
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (a -> CoreExpr) -> RuleFun
forall a. RealFloat a => (a -> CoreExpr) -> RuleFun
match_rationalTo a -> CoreExpr
mkLit }
builtinNaturalRules :: [CoreRule]
builtinNaturalRules :: [CoreRule]
builtinNaturalRules =
[String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"plusNatural" Name
plusNaturalName Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+)
,String -> Name -> (Integer -> Integer -> Maybe Integer) -> CoreRule
rule_partial_binop String
"minusNatural" Name
minusNaturalName (\Integer
a Integer
b -> if Integer
a Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
b then Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
b) else Maybe Integer
forall a. Maybe a
Nothing)
,String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
"timesNatural" Name
timesNaturalName Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*)
,String -> Name -> CoreRule
rule_NaturalFromInteger String
"naturalFromInteger" Name
naturalFromIntegerName
,String -> Name -> CoreRule
rule_NaturalToInteger String
"naturalToInteger" Name
naturalToIntegerName
,String -> Name -> CoreRule
rule_WordToNatural String
"wordToNatural" Name
wordToNaturalName
]
where rule_binop :: String -> Name -> (Integer -> Integer -> Integer) -> CoreRule
rule_binop String
str Name
name Integer -> Integer -> Integer
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> Integer) -> RuleFun
match_Natural_binop Integer -> Integer -> Integer
op }
rule_partial_binop :: String -> Name -> (Integer -> Integer -> Maybe Integer) -> CoreRule
rule_partial_binop String
str Name
name Integer -> Integer -> Maybe Integer
op
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
2,
ru_try :: RuleFun
ru_try = (Integer -> Integer -> Maybe Integer) -> RuleFun
match_Natural_partial_binop Integer -> Integer -> Maybe Integer
op }
rule_NaturalToInteger :: String -> Name -> CoreRule
rule_NaturalToInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_NaturalToInteger }
rule_NaturalFromInteger :: String -> Name -> CoreRule
rule_NaturalFromInteger String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_NaturalFromInteger }
rule_WordToNatural :: String -> Name -> CoreRule
rule_WordToNatural String
str Name
name
= BuiltinRule :: RuleName -> Name -> Int -> RuleFun -> CoreRule
BuiltinRule { ru_name :: RuleName
ru_name = String -> RuleName
fsLit String
str, ru_fn :: Name
ru_fn = Name
name, ru_nargs :: Int
ru_nargs = Int
1,
ru_try :: RuleFun
ru_try = RuleFun
match_WordToNatural }
match_append_lit :: RuleFun
match_append_lit :: RuleFun
match_append_lit DynFlags
_ InScopeEnv
id_unf CoreBndr
_
[ Type Type
ty1
, CoreExpr
lit1
, CoreExpr
c1
, CoreExpr
e2
]
| ([Tickish CoreBndr]
strTicks, Var CoreBndr
unpk `App` Type Type
ty2
`App` CoreExpr
lit2
`App` CoreExpr
c2
`App` CoreExpr
n) <- (Tickish CoreBndr -> Bool)
-> CoreExpr -> ([Tickish CoreBndr], CoreExpr)
forall b.
(Tickish CoreBndr -> Bool)
-> Expr b -> ([Tickish CoreBndr], Expr b)
stripTicksTop Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishFloatable CoreExpr
e2
, CoreBndr
unpk CoreBndr -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
unpackCStringFoldrIdKey
, (Tickish CoreBndr -> Bool) -> CoreExpr -> CoreExpr -> Bool
forall b. (Tickish CoreBndr -> Bool) -> Expr b -> Expr b -> Bool
cheapEqExpr' Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishFloatable CoreExpr
c1 CoreExpr
c2
, ([Tickish CoreBndr]
c1Ticks, CoreExpr
c1') <- (Tickish CoreBndr -> Bool)
-> CoreExpr -> ([Tickish CoreBndr], CoreExpr)
forall b.
(Tickish CoreBndr -> Bool)
-> Expr b -> ([Tickish CoreBndr], Expr b)
stripTicksTop Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishFloatable CoreExpr
c1
, [Tickish CoreBndr]
c2Ticks <- (Tickish CoreBndr -> Bool) -> CoreExpr -> [Tickish CoreBndr]
forall b.
(Tickish CoreBndr -> Bool) -> Expr b -> [Tickish CoreBndr]
stripTicksTopT Tickish CoreBndr -> Bool
forall id. Tickish id -> Bool
tickishFloatable CoreExpr
c2
, Just (LitString ByteString
s1) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
lit1
, Just (LitString ByteString
s2) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
lit2
= ASSERT( ty1 `eqType` ty2 )
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Tickish CoreBndr] -> CoreExpr -> CoreExpr
mkTicks [Tickish CoreBndr]
strTicks
(CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
unpk CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` Type -> CoreExpr
forall b. Type -> Expr b
Type Type
ty1
CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (ByteString -> Literal
LitString (ByteString
s1 ByteString -> ByteString -> ByteString
`BS.append` ByteString
s2))
CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` [Tickish CoreBndr] -> CoreExpr -> CoreExpr
mkTicks ([Tickish CoreBndr]
c1Ticks [Tickish CoreBndr] -> [Tickish CoreBndr] -> [Tickish CoreBndr]
forall a. [a] -> [a] -> [a]
++ [Tickish CoreBndr]
c2Ticks) CoreExpr
c1'
CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
n
match_append_lit DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_eq_string :: RuleFun
match_eq_string :: RuleFun
match_eq_string DynFlags
_ InScopeEnv
id_unf CoreBndr
_
[Var CoreBndr
unpk1 `App` CoreExpr
lit1, Var CoreBndr
unpk2 `App` CoreExpr
lit2]
| CoreBndr
unpk1 CoreBndr -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
unpackCStringIdKey
, CoreBndr
unpk2 CoreBndr -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
unpackCStringIdKey
, Just (LitString ByteString
s1) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
lit1
, Just (LitString ByteString
s2) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
lit2
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (if ByteString
s1 ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
s2 then CoreExpr
trueValBool else CoreExpr
falseValBool)
match_eq_string DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_inline :: [Expr CoreBndr] -> Maybe (Expr CoreBndr)
match_inline :: [CoreExpr] -> Maybe CoreExpr
match_inline (Type Type
_ : CoreExpr
e : [CoreExpr]
_)
| (Var CoreBndr
f, [CoreExpr]
args1) <- CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
e,
Just CoreExpr
unf <- Unfolding -> Maybe CoreExpr
maybeUnfoldingTemplate (CoreBndr -> Unfolding
realIdUnfolding CoreBndr
f)
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps CoreExpr
unf [CoreExpr]
args1)
match_inline [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_magicDict :: [Expr CoreBndr] -> Maybe (Expr CoreBndr)
match_magicDict :: [CoreExpr] -> Maybe CoreExpr
match_magicDict [Type Type
_, Var CoreBndr
wrap `App` Type Type
a `App` Type Type
_ `App` CoreExpr
f, CoreExpr
x, CoreExpr
y ]
| Just (Type
fieldTy, Type
_) <- Type -> Maybe (Type, Type)
splitFunTy_maybe (Type -> Maybe (Type, Type)) -> Type -> Maybe (Type, Type)
forall a b. (a -> b) -> a -> b
$ Type -> Type
dropForAlls (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ CoreBndr -> Type
idType CoreBndr
wrap
, Just (Type
dictTy, Type
_) <- Type -> Maybe (Type, Type)
splitFunTy_maybe Type
fieldTy
, Just TyCon
dictTc <- Type -> Maybe TyCon
tyConAppTyCon_maybe Type
dictTy
, Just ([CoreBndr]
_,Type
_,CoAxiom Unbranched
co) <- TyCon -> Maybe ([CoreBndr], Type, CoAxiom Unbranched)
unwrapNewTyCon_maybe TyCon
dictTc
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just
(CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr
f CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
x (Coercion -> Coercion
mkSymCo (Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational CoAxiom Unbranched
co [Type
a] []))
CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
`App` CoreExpr
y
match_magicDict [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_IntToInteger :: RuleFun
match_IntToInteger :: RuleFun
match_IntToInteger = (Integer -> Integer) -> RuleFun
match_IntToInteger_unop Integer -> Integer
forall a. a -> a
id
match_WordToInteger :: RuleFun
match_WordToInteger :: RuleFun
match_WordToInteger DynFlags
_ InScopeEnv
id_unf CoreBndr
id [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumWord Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
id) of
Just (Type
_, Type
integerTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger Integer
x Type
integerTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_WordToInteger: Id has the wrong type"
match_WordToInteger DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Int64ToInteger :: RuleFun
match_Int64ToInteger :: RuleFun
match_Int64ToInteger DynFlags
_ InScopeEnv
id_unf CoreBndr
id [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumInt64 Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
id) of
Just (Type
_, Type
integerTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger Integer
x Type
integerTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_Int64ToInteger: Id has the wrong type"
match_Int64ToInteger DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Word64ToInteger :: RuleFun
match_Word64ToInteger :: RuleFun
match_Word64ToInteger DynFlags
_ InScopeEnv
id_unf CoreBndr
id [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumWord64 Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
id) of
Just (Type
_, Type
integerTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger Integer
x Type
integerTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_Word64ToInteger: Id has the wrong type"
match_Word64ToInteger DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_NaturalToInteger :: RuleFun
match_NaturalToInteger :: RuleFun
match_NaturalToInteger DynFlags
_ InScopeEnv
id_unf CoreBndr
id [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumNatural Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
id) of
Just (Type
_, Type
naturalTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInteger Integer
x Type
naturalTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_NaturalToInteger: Id has the wrong type"
match_NaturalToInteger DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_NaturalFromInteger :: RuleFun
match_NaturalFromInteger :: RuleFun
match_NaturalFromInteger DynFlags
_ InScopeEnv
id_unf CoreBndr
id [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
id) of
Just (Type
_, Type
naturalTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumNatural Integer
x Type
naturalTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_NaturalFromInteger: Id has the wrong type"
match_NaturalFromInteger DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_WordToNatural :: RuleFun
match_WordToNatural :: RuleFun
match_WordToNatural DynFlags
_ InScopeEnv
id_unf CoreBndr
id [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumWord Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
id) of
Just (Type
_, Type
naturalTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumNatural Integer
x Type
naturalTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_WordToNatural: Id has the wrong type"
match_WordToNatural DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_bitInteger :: RuleFun
match_bitInteger :: RuleFun
match_bitInteger DynFlags
dflags InScopeEnv
id_unf CoreBndr
fn [CoreExpr
arg]
| Just (LitNumber LitNumType
LitNumInt Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
arg
, Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0
, Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= (DynFlags -> Integer
wordSizeInBits DynFlags
dflags Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
, let x_int :: Int
x_int = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x :: Int
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
fn) of
Just (Type
_, Type
integerTy)
-> CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInteger (Int -> Integer
forall a. Bits a => Int -> a
bit Int
x_int) Type
integerTy))
Maybe (Type, Type)
_ -> String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_IntToInteger_unop: Id has the wrong type"
match_bitInteger DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_convert :: Num a
=> (DynFlags -> a -> Expr CoreBndr)
-> RuleFun
match_Integer_convert :: (DynFlags -> a -> CoreExpr) -> RuleFun
match_Integer_convert DynFlags -> a -> CoreExpr
convert DynFlags
dflags InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (DynFlags -> a -> CoreExpr
convert DynFlags
dflags (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
x))
match_Integer_convert DynFlags -> a -> CoreExpr
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_unop :: (Integer -> Integer) -> RuleFun
match_Integer_unop :: (Integer -> Integer) -> RuleFun
match_Integer_unop Integer -> Integer
unop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
i) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInteger (Integer -> Integer
unop Integer
x) Type
i))
match_Integer_unop Integer -> Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_IntToInteger_unop :: (Integer -> Integer) -> RuleFun
match_IntToInteger_unop :: (Integer -> Integer) -> RuleFun
match_IntToInteger_unop Integer -> Integer
unop DynFlags
_ InScopeEnv
id_unf CoreBndr
fn [CoreExpr
xl]
| Just (LitNumber LitNumType
LitNumInt Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
fn) of
Just (Type
_, Type
integerTy) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Type -> Literal
LitNumber LitNumType
LitNumInteger (Integer -> Integer
unop Integer
x) Type
integerTy))
Maybe (Type, Type)
_ ->
String -> Maybe CoreExpr
forall a. String -> a
panic String
"match_IntToInteger_unop: Id has the wrong type"
match_IntToInteger_unop Integer -> Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_binop :: (Integer -> Integer -> Integer) -> RuleFun
match_Integer_binop :: (Integer -> Integer -> Integer) -> RuleFun
match_Integer_binop Integer -> Integer -> Integer
binop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
i) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInteger Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger (Integer
x Integer -> Integer -> Integer
`binop` Integer
y) Type
i))
match_Integer_binop Integer -> Integer -> Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Natural_binop :: (Integer -> Integer -> Integer) -> RuleFun
match_Natural_binop :: (Integer -> Integer -> Integer) -> RuleFun
match_Natural_binop Integer -> Integer -> Integer
binop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumNatural Integer
x Type
i) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumNatural Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitNatural (Integer
x Integer -> Integer -> Integer
`binop` Integer
y) Type
i))
match_Natural_binop Integer -> Integer -> Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Natural_partial_binop :: (Integer -> Integer -> Maybe Integer) -> RuleFun
match_Natural_partial_binop :: (Integer -> Integer -> Maybe Integer) -> RuleFun
match_Natural_partial_binop Integer -> Integer -> Maybe Integer
binop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumNatural Integer
x Type
i) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumNatural Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
, Just Integer
z <- Integer
x Integer -> Integer -> Maybe Integer
`binop` Integer
y
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitNatural Integer
z Type
i))
match_Natural_partial_binop Integer -> Integer -> Maybe Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_divop_both
:: (Integer -> Integer -> (Integer, Integer)) -> RuleFun
match_Integer_divop_both :: (Integer -> Integer -> (Integer, Integer)) -> RuleFun
match_Integer_divop_both Integer -> Integer -> (Integer, Integer)
divop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
t) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInteger Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
, Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
, (Integer
r,Integer
s) <- Integer
x Integer -> Integer -> (Integer, Integer)
`divop` Integer
y
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [Type
t,Type
t] [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger Integer
r Type
t), Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger Integer
s Type
t)]
match_Integer_divop_both Integer -> Integer -> (Integer, Integer)
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_divop_one :: (Integer -> Integer -> Integer) -> RuleFun
match_Integer_divop_one :: (Integer -> Integer -> Integer) -> RuleFun
match_Integer_divop_one Integer -> Integer -> Integer
divop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
i) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInteger Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
, Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger (Integer
x Integer -> Integer -> Integer
`divop` Integer
y) Type
i))
match_Integer_divop_one Integer -> Integer -> Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_shift_op :: (Integer -> Int -> Integer) -> RuleFun
match_Integer_shift_op :: (Integer -> Int -> Integer) -> RuleFun
match_Integer_shift_op Integer -> Int -> Integer
binop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
i) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInt Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
, Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0
, Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
4
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger (Integer
x Integer -> Int -> Integer
`binop` Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
y) Type
i))
match_Integer_shift_op Integer -> Int -> Integer
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_binop_Prim :: (Integer -> Integer -> Bool) -> RuleFun
match_Integer_binop_Prim :: (Integer -> Integer -> Bool) -> RuleFun
match_Integer_binop_Prim Integer -> Integer -> Bool
binop DynFlags
dflags InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl, CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInteger Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (if Integer
x Integer -> Integer -> Bool
`binop` Integer
y then DynFlags -> CoreExpr
trueValInt DynFlags
dflags else DynFlags -> CoreExpr
falseValInt DynFlags
dflags)
match_Integer_binop_Prim Integer -> Integer -> Bool
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_binop_Ordering :: (Integer -> Integer -> Ordering) -> RuleFun
match_Integer_binop_Ordering :: (Integer -> Integer -> Ordering) -> RuleFun
match_Integer_binop_Ordering Integer -> Integer -> Ordering
binop DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl, CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInteger Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ case Integer
x Integer -> Integer -> Ordering
`binop` Integer
y of
Ordering
LT -> CoreExpr
ltVal
Ordering
EQ -> CoreExpr
eqVal
Ordering
GT -> CoreExpr
gtVal
match_Integer_binop_Ordering Integer -> Integer -> Ordering
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_Integer_Int_encodeFloat :: RealFloat a
=> (a -> Expr CoreBndr)
-> RuleFun
match_Integer_Int_encodeFloat :: (a -> CoreExpr) -> RuleFun
match_Integer_Int_encodeFloat a -> CoreExpr
mkLit DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl,CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInt Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (a -> CoreExpr
mkLit (a -> CoreExpr) -> a -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
x (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
y))
match_Integer_Int_encodeFloat a -> CoreExpr
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_rationalTo :: RealFloat a
=> (a -> Expr CoreBndr)
-> RuleFun
match_rationalTo :: (a -> CoreExpr) -> RuleFun
match_rationalTo a -> CoreExpr
mkLit DynFlags
_ InScopeEnv
id_unf CoreBndr
_ [CoreExpr
xl, CoreExpr
yl]
| Just (LitNumber LitNumType
LitNumInteger Integer
x Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
, Just (LitNumber LitNumType
LitNumInteger Integer
y Type
_) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
yl
, Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (a -> CoreExpr
mkLit (Rational -> a
forall a. Fractional a => Rational -> a
fromRational (Integer
x Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
y)))
match_rationalTo a -> CoreExpr
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_decodeDouble :: RuleFun
match_decodeDouble :: RuleFun
match_decodeDouble DynFlags
dflags InScopeEnv
id_unf CoreBndr
fn [CoreExpr
xl]
| Just (LitDouble Rational
x) <- InScopeEnv -> CoreExpr -> Maybe Literal
exprIsLiteral_maybe InScopeEnv
id_unf CoreExpr
xl
= case Type -> Maybe (Type, Type)
splitFunTy_maybe (CoreBndr -> Type
idType CoreBndr
fn) of
Just (Type
_, Type
res)
| Just [Type
_lev1, Type
_lev2, Type
integerTy, Type
intHashTy] <- Type -> Maybe [Type]
tyConAppArgs_maybe Type
res
-> case Double -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
x :: Double) of
(Integer
y, Int
z) ->
CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ [Type] -> [CoreExpr] -> CoreExpr
mkCoreUbxTup [Type
integerTy, Type
intHashTy]
[Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (Integer -> Type -> Literal
mkLitInteger Integer
y Type
integerTy),
Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
z))]
Maybe (Type, Type)
_ ->
String -> SDoc -> Maybe CoreExpr
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"match_decodeDouble: Id has the wrong type"
(CoreBndr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreBndr
fn SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CoreBndr -> Type
idType CoreBndr
fn))
match_decodeDouble DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_XToIntegerToX :: Name -> RuleFun
match_XToIntegerToX :: Name -> RuleFun
match_XToIntegerToX Name
n DynFlags
_ InScopeEnv
_ CoreBndr
_ [App (Var CoreBndr
x) CoreExpr
y]
| CoreBndr -> Name
idName CoreBndr
x Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
n
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just CoreExpr
y
match_XToIntegerToX Name
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
match_smallIntegerTo :: PrimOp -> RuleFun
match_smallIntegerTo :: PrimOp -> RuleFun
match_smallIntegerTo PrimOp
primOp DynFlags
_ InScopeEnv
_ CoreBndr
_ [App (Var CoreBndr
x) CoreExpr
y]
| CoreBndr -> Name
idName CoreBndr
x Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
smallIntegerName
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (PrimOp -> CoreBndr
mkPrimOpId PrimOp
primOp)) CoreExpr
y
match_smallIntegerTo PrimOp
_ DynFlags
_ InScopeEnv
_ CoreBndr
_ [CoreExpr]
_ = Maybe CoreExpr
forall a. Maybe a
Nothing
numFoldingRules :: PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules :: PrimOp -> (DynFlags -> PrimOps) -> RuleM CoreExpr
numFoldingRules PrimOp
op DynFlags -> PrimOps
dict = do
[CoreExpr
e1,CoreExpr
e2] <- RuleM [CoreExpr]
getArgs
DynFlags
dflags <- RuleM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
let PrimOps{Integer -> CoreExpr
CoreExpr -> CoreExpr -> CoreExpr
mkL :: PrimOps -> Integer -> CoreExpr
mul :: PrimOps -> CoreExpr -> CoreExpr -> CoreExpr
sub :: PrimOps -> CoreExpr -> CoreExpr -> CoreExpr
add :: PrimOps -> CoreExpr -> CoreExpr -> CoreExpr
mkL :: Integer -> CoreExpr
mul :: CoreExpr -> CoreExpr -> CoreExpr
sub :: CoreExpr -> CoreExpr -> CoreExpr
add :: CoreExpr -> CoreExpr -> CoreExpr
..} = DynFlags -> PrimOps
dict DynFlags
dflags
if Bool -> Bool
not (GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_NumConstantFolding DynFlags
dflags)
then RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a
mzero
else case CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
e1 PrimOp
op CoreExpr
e2 of
Integer
x :++: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v
Integer
x :++: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v
Integer
x :++: (CoreExpr
v :-: L Integer
y) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v
L Integer
x :-: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v
L Integer
x :-: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v
L Integer
x :-: (CoreExpr
v :-: L Integer
y) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v
(Integer
y :++: CoreExpr
v) :-: L Integer
x -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v
(L Integer
y :-: CoreExpr
v) :-: L Integer
x -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v
(CoreExpr
v :-: L Integer
y) :-: L Integer
x -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
0Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v
(Integer
x :++: CoreExpr
w) :+: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
(CoreExpr
w :-: L Integer
x) :+: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v)
(CoreExpr
w :-: L Integer
x) :+: (CoreExpr
v :-: L Integer
y) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
0Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
(L Integer
x :-: CoreExpr
w) :+: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
(L Integer
x :-: CoreExpr
w) :+: (CoreExpr
v :-: L Integer
y) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
w)
(CoreExpr
w :-: L Integer
x) :+: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
(L Integer
x :-: CoreExpr
w) :+: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
w)
(Integer
y :++: CoreExpr
v) :+: (CoreExpr
w :-: L Integer
x) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
(Integer
y :++: CoreExpr
v) :+: (L Integer
x :-: CoreExpr
w) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
w)
(CoreExpr
v :-: L Integer
y) :-: (CoreExpr
w :-: L Integer
x) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
w)
(CoreExpr
v :-: L Integer
y) :-: (L Integer
x :-: CoreExpr
w) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
0Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
w)
(L Integer
y :-: CoreExpr
v) :-: (CoreExpr
w :-: L Integer
x) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
w)
(L Integer
y :-: CoreExpr
v) :-: (L Integer
x :-: CoreExpr
w) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v)
(Integer
x :++: CoreExpr
w) :-: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v)
(CoreExpr
w :-: L Integer
x) :-: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
0Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v)
(L Integer
x :-: CoreExpr
w) :-: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
w)
(Integer
y :++: CoreExpr
v) :-: (CoreExpr
w :-: L Integer
x) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
w)
(Integer
y :++: CoreExpr
v) :-: (L Integer
x :-: CoreExpr
w) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
x) CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
w)
Integer
x :**: (Integer
y :**: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
(Integer
x :**: CoreExpr
w) :*: (Integer
y :**: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`mul` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v)
Integer
x :**: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`add` (Integer -> CoreExpr
mkL Integer
x CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v)
Integer
x :**: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`sub` (Integer -> CoreExpr
mkL Integer
x CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v)
Integer
x :**: (CoreExpr
v :-: L Integer
y) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ (Integer -> CoreExpr
mkL Integer
x CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v) CoreExpr -> CoreExpr -> CoreExpr
`sub` Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
y)
CoreExpr
v :+: CoreExpr
w
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
2 CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
CoreExpr
w :+: (Integer
y :**: CoreExpr
v)
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
1Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
CoreExpr
w :-: (Integer
y :**: CoreExpr
v)
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
1Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
(Integer
y :**: CoreExpr
v) :+: CoreExpr
w
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
(Integer
y :**: CoreExpr
v) :-: CoreExpr
w
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
(Integer
x :**: CoreExpr
w) :+: (Integer
y :**: CoreExpr
v)
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
(Integer
x :**: CoreExpr
w) :-: (Integer
y :**: CoreExpr
v)
| CoreExpr
w CoreExpr -> CoreExpr -> Bool
forall b. Expr b -> Expr b -> Bool
`cheapEqExpr` CoreExpr
v -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL (Integer
xInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y) CoreExpr -> CoreExpr -> CoreExpr
`mul` CoreExpr
v
CoreExpr
w :+: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
y CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
(Integer
y :++: CoreExpr
v) :+: CoreExpr
w -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
y CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
CoreExpr
w :-: (Integer
y :++: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v) CoreExpr -> CoreExpr -> CoreExpr
`sub` Integer -> CoreExpr
mkL Integer
y
(Integer
y :++: CoreExpr
v) :-: CoreExpr
w -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
y CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
v CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
w)
CoreExpr
w :-: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v) CoreExpr -> CoreExpr -> CoreExpr
`sub` Integer -> CoreExpr
mkL Integer
y
(L Integer
y :-: CoreExpr
v) :-: CoreExpr
w -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
y CoreExpr -> CoreExpr -> CoreExpr
`sub` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v)
CoreExpr
w :+: (L Integer
y :-: CoreExpr
v) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
y CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v)
CoreExpr
w :+: (CoreExpr
v :-: L Integer
y) -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v) CoreExpr -> CoreExpr -> CoreExpr
`sub` Integer -> CoreExpr
mkL Integer
y
(L Integer
y :-: CoreExpr
v) :+: CoreExpr
w -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ Integer -> CoreExpr
mkL Integer
y CoreExpr -> CoreExpr -> CoreExpr
`add` (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`sub` CoreExpr
v)
(CoreExpr
v :-: L Integer
y) :+: CoreExpr
w -> CoreExpr -> RuleM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> RuleM CoreExpr) -> CoreExpr -> RuleM CoreExpr
forall a b. (a -> b) -> a -> b
$ (CoreExpr
w CoreExpr -> CoreExpr -> CoreExpr
`add` CoreExpr
v) CoreExpr -> CoreExpr -> CoreExpr
`sub` Integer -> CoreExpr
mkL Integer
y
CoreExpr
_ -> RuleM CoreExpr
forall (m :: * -> *) a. MonadPlus m => m a
mzero
pattern BinOpApp :: Arg CoreBndr -> PrimOp -> Arg CoreBndr -> CoreExpr
pattern $bBinOpApp :: CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
$mBinOpApp :: forall r.
CoreExpr
-> (CoreExpr -> PrimOp -> CoreExpr -> r) -> (Void# -> r) -> r
BinOpApp x op y = OpVal op `App` x `App` y
pattern OpVal :: PrimOp -> Arg CoreBndr
pattern $bOpVal :: PrimOp -> CoreExpr
$mOpVal :: forall r. CoreExpr -> (PrimOp -> r) -> (Void# -> r) -> r
OpVal op <- Var (isPrimOpId_maybe -> Just op) where
OpVal PrimOp
op = CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var (PrimOp -> CoreBndr
mkPrimOpId PrimOp
op)
pattern L :: Integer -> Arg CoreBndr
pattern $mL :: forall r. CoreExpr -> (Integer -> r) -> (Void# -> r) -> r
L l <- Lit (isLitValue_maybe -> Just l)
pattern (:+:) :: Arg CoreBndr -> Arg CoreBndr -> CoreExpr
pattern x $m:+: :: forall r.
CoreExpr -> (CoreExpr -> CoreExpr -> r) -> (Void# -> r) -> r
:+: y <- BinOpApp x (isAddOp -> True) y
pattern (:++:) :: Integer -> Arg CoreBndr -> CoreExpr
pattern l $m:++: :: forall r.
CoreExpr -> (Integer -> CoreExpr -> r) -> (Void# -> r) -> r
:++: x <- (isAdd -> Just (l,x))
isAdd :: CoreExpr -> Maybe (Integer,CoreExpr)
isAdd :: CoreExpr -> Maybe (Integer, CoreExpr)
isAdd CoreExpr
e = case CoreExpr
e of
L Integer
l :+: CoreExpr
x -> (Integer, CoreExpr) -> Maybe (Integer, CoreExpr)
forall a. a -> Maybe a
Just (Integer
l,CoreExpr
x)
CoreExpr
x :+: L Integer
l -> (Integer, CoreExpr) -> Maybe (Integer, CoreExpr)
forall a. a -> Maybe a
Just (Integer
l,CoreExpr
x)
CoreExpr
_ -> Maybe (Integer, CoreExpr)
forall a. Maybe a
Nothing
pattern (:*:) :: Arg CoreBndr -> Arg CoreBndr -> CoreExpr
pattern x $m:*: :: forall r.
CoreExpr -> (CoreExpr -> CoreExpr -> r) -> (Void# -> r) -> r
:*: y <- BinOpApp x (isMulOp -> True) y
pattern (:**:) :: Integer -> Arg CoreBndr -> CoreExpr
pattern l $m:**: :: forall r.
CoreExpr -> (Integer -> CoreExpr -> r) -> (Void# -> r) -> r
:**: x <- (isMul -> Just (l,x))
isMul :: CoreExpr -> Maybe (Integer,CoreExpr)
isMul :: CoreExpr -> Maybe (Integer, CoreExpr)
isMul CoreExpr
e = case CoreExpr
e of
L Integer
l :*: CoreExpr
x -> (Integer, CoreExpr) -> Maybe (Integer, CoreExpr)
forall a. a -> Maybe a
Just (Integer
l,CoreExpr
x)
CoreExpr
x :*: L Integer
l -> (Integer, CoreExpr) -> Maybe (Integer, CoreExpr)
forall a. a -> Maybe a
Just (Integer
l,CoreExpr
x)
CoreExpr
_ -> Maybe (Integer, CoreExpr)
forall a. Maybe a
Nothing
pattern (:-:) :: Arg CoreBndr -> Arg CoreBndr -> CoreExpr
pattern x $m:-: :: forall r.
CoreExpr -> (CoreExpr -> CoreExpr -> r) -> (Void# -> r) -> r
:-: y <- BinOpApp x (isSubOp -> True) y
isSubOp :: PrimOp -> Bool
isSubOp :: PrimOp -> Bool
isSubOp PrimOp
IntSubOp = Bool
True
isSubOp PrimOp
WordSubOp = Bool
True
isSubOp PrimOp
_ = Bool
False
isAddOp :: PrimOp -> Bool
isAddOp :: PrimOp -> Bool
isAddOp PrimOp
IntAddOp = Bool
True
isAddOp PrimOp
WordAddOp = Bool
True
isAddOp PrimOp
_ = Bool
False
isMulOp :: PrimOp -> Bool
isMulOp :: PrimOp -> Bool
isMulOp PrimOp
IntMulOp = Bool
True
isMulOp PrimOp
WordMulOp = Bool
True
isMulOp PrimOp
_ = Bool
False
data PrimOps = PrimOps
{ PrimOps -> CoreExpr -> CoreExpr -> CoreExpr
add :: CoreExpr -> CoreExpr -> CoreExpr
, PrimOps -> CoreExpr -> CoreExpr -> CoreExpr
sub :: CoreExpr -> CoreExpr -> CoreExpr
, PrimOps -> CoreExpr -> CoreExpr -> CoreExpr
mul :: CoreExpr -> CoreExpr -> CoreExpr
, PrimOps -> Integer -> CoreExpr
mkL :: Integer -> CoreExpr
}
intPrimOps :: DynFlags -> PrimOps
intPrimOps :: DynFlags -> PrimOps
intPrimOps DynFlags
dflags = PrimOps :: (CoreExpr -> CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr -> CoreExpr)
-> (Integer -> CoreExpr)
-> PrimOps
PrimOps
{ add :: CoreExpr -> CoreExpr -> CoreExpr
add = \CoreExpr
x CoreExpr
y -> CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
x PrimOp
IntAddOp CoreExpr
y
, sub :: CoreExpr -> CoreExpr -> CoreExpr
sub = \CoreExpr
x CoreExpr
y -> CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
x PrimOp
IntSubOp CoreExpr
y
, mul :: CoreExpr -> CoreExpr -> CoreExpr
mul = \CoreExpr
x CoreExpr
y -> CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
x PrimOp
IntMulOp CoreExpr
y
, mkL :: Integer -> CoreExpr
mkL = DynFlags -> Integer -> CoreExpr
intResult' DynFlags
dflags
}
wordPrimOps :: DynFlags -> PrimOps
wordPrimOps :: DynFlags -> PrimOps
wordPrimOps DynFlags
dflags = PrimOps :: (CoreExpr -> CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr -> CoreExpr)
-> (CoreExpr -> CoreExpr -> CoreExpr)
-> (Integer -> CoreExpr)
-> PrimOps
PrimOps
{ add :: CoreExpr -> CoreExpr -> CoreExpr
add = \CoreExpr
x CoreExpr
y -> CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
x PrimOp
WordAddOp CoreExpr
y
, sub :: CoreExpr -> CoreExpr -> CoreExpr
sub = \CoreExpr
x CoreExpr
y -> CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
x PrimOp
WordSubOp CoreExpr
y
, mul :: CoreExpr -> CoreExpr -> CoreExpr
mul = \CoreExpr
x CoreExpr
y -> CoreExpr -> PrimOp -> CoreExpr -> CoreExpr
BinOpApp CoreExpr
x PrimOp
WordMulOp CoreExpr
y
, mkL :: Integer -> CoreExpr
mkL = DynFlags -> Integer -> CoreExpr
wordResult' DynFlags
dflags
}
caseRules :: DynFlags
-> CoreExpr
-> Maybe ( CoreExpr
, AltCon -> Maybe AltCon
, Id -> CoreExpr)
caseRules :: DynFlags
-> CoreExpr
-> Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
caseRules DynFlags
dflags (App (App (Var CoreBndr
f) CoreExpr
v) (Lit Literal
l))
| Just PrimOp
op <- CoreBndr -> Maybe PrimOp
isPrimOpId_maybe CoreBndr
f
, Just Integer
x <- Literal -> Maybe Integer
isLitValue_maybe Literal
l
, Just Integer -> Integer
adjust_lit <- PrimOp -> Integer -> Maybe (Integer -> Integer)
adjustDyadicRight PrimOp
op Integer
x
= (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
-> Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
forall a. a -> Maybe a
Just (CoreExpr
v, DynFlags -> (Integer -> Integer) -> AltCon -> Maybe AltCon
tx_lit_con DynFlags
dflags Integer -> Integer
adjust_lit
, \CoreBndr
v -> (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
f) (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
v)) (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l)))
caseRules DynFlags
dflags (App (App (Var CoreBndr
f) (Lit Literal
l)) CoreExpr
v)
| Just PrimOp
op <- CoreBndr -> Maybe PrimOp
isPrimOpId_maybe CoreBndr
f
, Just Integer
x <- Literal -> Maybe Integer
isLitValue_maybe Literal
l
, Just Integer -> Integer
adjust_lit <- Integer -> PrimOp -> Maybe (Integer -> Integer)
adjustDyadicLeft Integer
x PrimOp
op
= (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
-> Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
forall a. a -> Maybe a
Just (CoreExpr
v, DynFlags -> (Integer -> Integer) -> AltCon -> Maybe AltCon
tx_lit_con DynFlags
dflags Integer -> Integer
adjust_lit
, \CoreBndr
v -> (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
f) (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l)) (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
v)))
caseRules DynFlags
dflags (App (Var CoreBndr
f) CoreExpr
v )
| Just PrimOp
op <- CoreBndr -> Maybe PrimOp
isPrimOpId_maybe CoreBndr
f
, Just Integer -> Integer
adjust_lit <- PrimOp -> Maybe (Integer -> Integer)
adjustUnary PrimOp
op
= (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
-> Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
forall a. a -> Maybe a
Just (CoreExpr
v, DynFlags -> (Integer -> Integer) -> AltCon -> Maybe AltCon
tx_lit_con DynFlags
dflags Integer -> Integer
adjust_lit
, \CoreBndr
v -> CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
f) (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
v))
caseRules DynFlags
dflags (App (App (Var CoreBndr
f) CoreExpr
type_arg) CoreExpr
v)
| Just PrimOp
TagToEnumOp <- CoreBndr -> Maybe PrimOp
isPrimOpId_maybe CoreBndr
f
= (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
-> Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
forall a. a -> Maybe a
Just (CoreExpr
v, DynFlags -> AltCon -> Maybe AltCon
tx_con_tte DynFlags
dflags
, \CoreBndr
v -> (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
f) CoreExpr
type_arg) (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
v)))
caseRules DynFlags
_ (App (App (Var CoreBndr
f) (Type Type
ty)) CoreExpr
v)
| Just PrimOp
DataToTagOp <- CoreBndr -> Maybe PrimOp
isPrimOpId_maybe CoreBndr
f
, Just (TyCon
tc, [Type]
_) <- HasCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe Type
ty
, TyCon -> Bool
isAlgTyCon TyCon
tc
= (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
-> Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
forall a. a -> Maybe a
Just (CoreExpr
v, Type -> AltCon -> Maybe AltCon
tx_con_dtt Type
ty
, \CoreBndr
v -> CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
f) (Type -> CoreExpr
forall b. Type -> Expr b
Type Type
ty)) (CoreBndr -> CoreExpr
forall b. CoreBndr -> Expr b
Var CoreBndr
v))
caseRules DynFlags
_ CoreExpr
_ = Maybe (CoreExpr, AltCon -> Maybe AltCon, CoreBndr -> CoreExpr)
forall a. Maybe a
Nothing
tx_lit_con :: DynFlags -> (Integer -> Integer) -> AltCon -> Maybe AltCon
tx_lit_con :: DynFlags -> (Integer -> Integer) -> AltCon -> Maybe AltCon
tx_lit_con DynFlags
_ Integer -> Integer
_ AltCon
DEFAULT = AltCon -> Maybe AltCon
forall a. a -> Maybe a
Just AltCon
DEFAULT
tx_lit_con DynFlags
dflags Integer -> Integer
adjust (LitAlt Literal
l) = AltCon -> Maybe AltCon
forall a. a -> Maybe a
Just (AltCon -> Maybe AltCon) -> AltCon -> Maybe AltCon
forall a b. (a -> b) -> a -> b
$ Literal -> AltCon
LitAlt (DynFlags -> (Integer -> Integer) -> Literal -> Literal
mapLitValue DynFlags
dflags Integer -> Integer
adjust Literal
l)
tx_lit_con DynFlags
_ Integer -> Integer
_ AltCon
alt = String -> SDoc -> Maybe AltCon
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"caseRules" (AltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltCon
alt)
adjustDyadicRight :: PrimOp -> Integer -> Maybe (Integer -> Integer)
adjustDyadicRight :: PrimOp -> Integer -> Maybe (Integer -> Integer)
adjustDyadicRight PrimOp
op Integer
lit
= case PrimOp
op of
PrimOp
WordAddOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
lit )
PrimOp
IntAddOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
lit )
PrimOp
WordSubOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
lit )
PrimOp
IntSubOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
lit )
PrimOp
XorOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
y Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
`xor` Integer
lit)
PrimOp
XorIOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
y Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
`xor` Integer
lit)
PrimOp
_ -> Maybe (Integer -> Integer)
forall a. Maybe a
Nothing
adjustDyadicLeft :: Integer -> PrimOp -> Maybe (Integer -> Integer)
adjustDyadicLeft :: Integer -> PrimOp -> Maybe (Integer -> Integer)
adjustDyadicLeft Integer
lit PrimOp
op
= case PrimOp
op of
PrimOp
WordAddOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
lit )
PrimOp
IntAddOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
lit )
PrimOp
WordSubOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
litInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y )
PrimOp
IntSubOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
litInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
y )
PrimOp
XorOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
y Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
`xor` Integer
lit)
PrimOp
XorIOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer
y Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
`xor` Integer
lit)
PrimOp
_ -> Maybe (Integer -> Integer)
forall a. Maybe a
Nothing
adjustUnary :: PrimOp -> Maybe (Integer -> Integer)
adjustUnary :: PrimOp -> Maybe (Integer -> Integer)
adjustUnary PrimOp
op
= case PrimOp
op of
PrimOp
NotOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer -> Integer
forall a. Bits a => a -> a
complement Integer
y)
PrimOp
NotIOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer -> Integer
forall a. Bits a => a -> a
complement Integer
y)
PrimOp
IntNegOp -> (Integer -> Integer) -> Maybe (Integer -> Integer)
forall a. a -> Maybe a
Just (\Integer
y -> Integer -> Integer
forall a. Num a => a -> a
negate Integer
y )
PrimOp
_ -> Maybe (Integer -> Integer)
forall a. Maybe a
Nothing
tx_con_tte :: DynFlags -> AltCon -> Maybe AltCon
tx_con_tte :: DynFlags -> AltCon -> Maybe AltCon
tx_con_tte DynFlags
_ AltCon
DEFAULT = AltCon -> Maybe AltCon
forall a. a -> Maybe a
Just AltCon
DEFAULT
tx_con_tte DynFlags
_ alt :: AltCon
alt@(LitAlt {}) = String -> SDoc -> Maybe AltCon
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"caseRules" (AltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltCon
alt)
tx_con_tte DynFlags
dflags (DataAlt DataCon
dc)
= AltCon -> Maybe AltCon
forall a. a -> Maybe a
Just (AltCon -> Maybe AltCon) -> AltCon -> Maybe AltCon
forall a b. (a -> b) -> a -> b
$ Literal -> AltCon
LitAlt (Literal -> AltCon) -> Literal -> AltCon
forall a b. (a -> b) -> a -> b
$ DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags (Integer -> Literal) -> Integer -> Literal
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ DataCon -> Int
dataConTagZ DataCon
dc
tx_con_dtt :: Type -> AltCon -> Maybe AltCon
tx_con_dtt :: Type -> AltCon -> Maybe AltCon
tx_con_dtt Type
_ AltCon
DEFAULT = AltCon -> Maybe AltCon
forall a. a -> Maybe a
Just AltCon
DEFAULT
tx_con_dtt Type
ty (LitAlt (LitNumber LitNumType
LitNumInt Integer
i Type
_))
| Int
tag Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
, Int
tag Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n_data_cons
= AltCon -> Maybe AltCon
forall a. a -> Maybe a
Just (DataCon -> AltCon
DataAlt ([DataCon]
data_cons [DataCon] -> Int -> DataCon
forall a. [a] -> Int -> a
!! Int
tag))
| Bool
otherwise
= Maybe AltCon
forall a. Maybe a
Nothing
where
tag :: Int
tag = Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
i :: ConTagZ
tc :: TyCon
tc = Type -> TyCon
tyConAppTyCon Type
ty
n_data_cons :: Int
n_data_cons = TyCon -> Int
tyConFamilySize TyCon
tc
data_cons :: [DataCon]
data_cons = TyCon -> [DataCon]
tyConDataCons TyCon
tc
tx_con_dtt Type
_ AltCon
alt = String -> SDoc -> Maybe AltCon
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"caseRules" (AltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr AltCon
alt)