{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ScopedTypeVariables #-} module Tip.Unfoldings (unfolding,maybeUnfolding,fixUnfoldings,fixId) where import qualified Data.Map as M import Control.Applicative import Data.Traversable (sequenceA) import Control.Monad.Reader import CoreSyn import CoreUnfold import Id import Data.Maybe import Tip.GHCUtils import Tip.Dicts -- | The unfolding of an Id unfolding :: Id -> CoreExpr unfolding i = fromMaybe (error err) . maybeUnfolding $ i where err = "No unfolding for identifier " ++ showOutputable i ++ " (possible solution: Remove *.hi files and try again)" -- | Fixes identifiers according to some core binds fixId :: [(Var,CoreExpr)] -> Id -> Id fixId bs = \ i -> case M.lookup i bind_map of Just rhs -> i `setIdUnfoldingLazily` mkInlineUnfolding Nothing rhs Nothing -> i where bind_map = M.fromList bs -- | Ties the knot, fixes all the unfoldings in these core binds fixUnfoldings :: [(Var,CoreExpr)] -> [(Var,CoreExpr)] fixUnfoldings bs = map (idMap lkup) bs' where bs' :: [(Var,CoreExpr)] bs' = mapM (exprMap k) bs lkup lkup :: Id -> Id lkup = fixId bs' h :: Id -> (Id -> Id) -> Id h x = do m <- ask return (m x) k :: CoreExpr -> (Id -> Id) -> CoreExpr k = boringCases h k -- | Maps an expression fun over binds exprMap :: Applicative f => (CoreExpr -> f CoreExpr) -> (Var,CoreExpr) -> f (Var,CoreExpr) exprMap f (v,e) = (,) v <$> f e -- | Maps an identifier fun over binds idMap :: (Id -> Id) -> (Var,CoreExpr) -> (Var,CoreExpr) idMap f (v,e) = (f v,e) bindMap :: Applicative f => (CoreExpr -> f CoreExpr) -> CoreBind -> f CoreBind bindMap f (NonRec v e) = NonRec v <$> f e bindMap f (Rec vses) = Rec <$> sequenceA [ (,) v <$> f e | (v,e) <- vses ] {- -- | Maps an expression fun over binds exprMap :: Applicative f => (CoreExpr -> f CoreExpr) -> CoreBind -> f CoreBind exprMap f (NonRec v e) = NonRec v <$> f e exprMap f (Rec vses) = Rec <$> sequenceA [ (,) v <$> f e | (v,e) <- vses ] -- | Maps an identifier fun over binds idMap :: (Id -> Id) -> CoreBind -> CoreBind idMap f (NonRec v e) = NonRec (f v) e idMap f (Rec vses) = Rec [ (f v,e) | (v,e) <- vses ] -} -- | Fills in all boring cases for you boringCases :: Applicative f => (Var -> f Var) -> (CoreExpr -> f CoreExpr) -> CoreExpr -> f CoreExpr boringCases h f t = case t of Var x -> Var <$> h x Lit{} -> pure t App e1 e2 -> App <$> f e1 <*> f e2 Lam x e -> Lam x <$> f e Let bs e -> Let <$> bindMap f bs <*> f e Case s ty w alts -> (\s' alts' -> Case s' ty w alts') <$> f s <*> sequenceA [ (,,) p bs <$> f e | (p,bs,e) <- alts ] Cast e co -> (`Cast` co) <$> f e Tick tk e -> Tick tk <$> f e Type{} -> pure t Coercion{} -> pure t