+
+
+
+\begin{code}
+--
+-- Simplification routines run before the flattener. We can't use
+-- simpleOptPgm -- it doesn't preserve the order of subexpressions or
+-- let-binding groups.
+--
+simplify :: Expr CoreBndr -> Expr CoreBndr
+simplify (Var v) = Var v
+simplify (App e1 e2) = App (simplify e1) (simplify e2)
+simplify (Lit lit) = Lit lit
+simplify (Note note e) = Note note (simplify e)
+simplify (Cast e co) = if tcEqType (fst $ coercionKind co) (snd $ coercionKind co)
+ then simplify e
+ else Cast (simplify e) co
+simplify (Lam v e) = Lam v (simplify e)
+simplify (Type t) = Type t
+simplify (Case e b ty as) = Case (simplify e) b ty (map (\(a,b,e) -> (a,b,simplify e)) as)
+simplify (Let bind body) = foldr Let (simplify body) (simplifyBind bind)
+
+simplifyBind :: Bind CoreBndr -> [Bind CoreBndr]
+simplifyBind (NonRec b e) = [NonRec b (simplify e)]
+simplifyBind (Rec []) = []
+simplifyBind (Rec (rbs@((b,e):rbs'))) =
+ if or $ map (\x -> elemUFM x (exprFreeIds e)) (map fst rbs)
+ then [Rec (map (\(v,e) -> (v,simplify e)) rbs)]
+ else (NonRec b (simplify e)):(simplifyBind $ Rec rbs')
+
+simplifyBinds = concatMap simplifyBind
+\end{code}
\ No newline at end of file