X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=c%CE%BBash%2FCLasH%2FNormalize.hs;h=9828d5ceea96704f92b979766dd06be5bfcc7523;hb=cba006ca253e6fcb39c0a82022e9704672997d3a;hp=1d40f92d52f7b94989fc9215bcfd15723a9001e0;hpb=4e12174b5b6515c056d4f83edcc18b991c71465d;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git "a/c\316\273ash/CLasH/Normalize.hs" "b/c\316\273ash/CLasH/Normalize.hs" index 1d40f92..9828d5c 100644 --- "a/c\316\273ash/CLasH/Normalize.hs" +++ "b/c\316\273ash/CLasH/Normalize.hs" @@ -9,6 +9,7 @@ module CLasH.Normalize (getNormalized, normalizeExpr, splitNormalized) where -- Standard modules import Debug.Trace import qualified Maybe +import qualified List import qualified "transformers" Control.Monad.Trans as Trans import qualified Control.Monad as Monad import qualified Control.Monad.Trans.Writer as Writer @@ -115,14 +116,31 @@ castsimpl expr = return expr castsimpltop = everywhere ("castsimpl", castsimpl) -------------------------------- --- let recursification +-- let derecursification -------------------------------- -letrec, letrectop :: Transform -letrec (Let (NonRec b expr) res) = change $ Let (Rec [(b, expr)]) res +letderec, letderectop :: Transform +letderec expr@(Let (Rec binds) res) = case liftable of + -- Nothing is liftable, just return + [] -> return expr + -- Something can be lifted, generate a new let expression + _ -> change $ MkCore.mkCoreLets newbinds res + where + -- Make a list of all the binders bound in this recursive let + bndrs = map fst binds + -- See which bindings are liftable + (liftable, nonliftable) = List.partition canlift binds + -- Create nonrec bindings for each liftable binding and a single recursive + -- binding for all others + newbinds = (map (uncurry NonRec) liftable) ++ [Rec nonliftable] + -- Any expression that does not use any of the binders in this recursive let + -- can be lifted into a nonrec let. It can't use its own binder either, + -- since that would mean the binding is self-recursive and should be in a + -- single bind recursive let. + canlift (bndr, e) = not $ expr_uses_binders bndrs e -- Leave all other expressions unchanged -letrec expr = return expr +letderec expr = return expr -- Perform this transform everywhere -letrectop = everywhere ("letrec", letrec) +letderectop = everywhere ("letderec", letderec) -------------------------------- -- let simplification @@ -545,7 +563,7 @@ funextracttop = everywhere ("funextract", funextract) -- What transforms to run? -transforms = [argproptop, funextracttop, etatop, betatop, castproptop, letremovetop, letrectop, letsimpltop, letflattop, scrutsimpltop, casesimpltop, caseremovetop, inlinenonreptop, appsimpltop, letmergetop, letremoveunusedtop, castsimpltop] +transforms = [argproptop, funextracttop, etatop, betatop, castproptop, letremovetop, letderectop, letsimpltop, letflattop, scrutsimpltop, casesimpltop, caseremovetop, inlinenonreptop, appsimpltop, letmergetop, letremoveunusedtop, castsimpltop] -- | Returns the normalized version of the given function. getNormalized ::