-- let simplification
--------------------------------
letsimpl, letsimpltop :: Transform
+-- Don't simplify a let that evaluates to another let, since this is already
+-- normal form (and would cause infinite loops with letflat below).
+letsimpl expr@(Let _ (Let _ _)) = return expr
-- Put the "in ..." value of a let in its own binding, but not when the
-- expression is already a local variable, or not representable (to prevent loops with inlinenonrep).
letsimpl expr@(Let binds res) = do
-- Perform this transform everywhere
letflattop = everywhere ("letflat", letflat)
+--------------------------------
+-- empty let removal
+--------------------------------
+-- Remove empty (recursive) lets
+letremove, letremovetop :: Transform
+letremove (Let (Rec []) res) = change $ res
+-- Leave all other expressions unchanged
+letremove expr = return expr
+-- Perform this transform everywhere
+letremovetop = everywhere ("letremove", letremove)
+
--------------------------------
-- Simple let binding removal
--------------------------------
-- Remove a = b bindings from let expressions everywhere
-letremovetop :: Transform
-letremovetop = everywhere ("letremove", inlinebind (\(b, e) -> Trans.lift $ is_local_var e))
+letremovesimpletop :: Transform
+letremovesimpletop = everywhere ("letremovesimple", inlinebind (\(b, e) -> Trans.lift $ is_local_var e))
--------------------------------
-- Unused let binding removal
-- What transforms to run?
-transforms = [argproptop, funextracttop, etatop, betatop, castproptop, letremovetop, letderectop, letsimpltop, letflattop, scrutsimpltop, casesimpltop, caseremovetop, inlinenonreptop, appsimpltop, letmergetop, letremoveunusedtop, castsimpltop]
+transforms = [argproptop, funextracttop, etatop, betatop, castproptop, letremovesimpletop, letderectop, letremovetop, letsimpltop, letflattop, scrutsimpltop, casesimpltop, caseremovetop, inlinenonreptop, appsimpltop, letmergetop, letremoveunusedtop, castsimpltop]
-- | Returns the normalized version of the given function.
getNormalized ::
res = case resexpr of
(Var x) -> x
_ -> error $ "Normalize.splitNormalized: Not in normal form: " ++ pprString expr ++ "\n"
-
--- | Flattens nested lets into a single list of bindings. The expression
--- passed does not have to be a let expression, if it isn't an empty list of
--- bindings is returned.
-flattenLets ::
- CoreExpr -- ^ The expression to flatten.
- -> ([Binding], CoreExpr) -- ^ The bindings and resulting expression.
-flattenLets (Let binds expr) =
- (bindings ++ bindings', expr')
- where
- -- Recursively flatten the contained expression
- (bindings', expr') =flattenLets expr
- -- Flatten our own bindings to remove the Rec / NonRec constructors
- bindings = CoreSyn.flattenBinds [binds]
-flattenLets expr = ([], expr)