X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=c%CE%BBash%2FCLasH%2FNormalize.hs;h=d66a1885be7062ea207561d4b17762b07f551033;hb=9fb1f6af219599d84cb085061b126b30db16a165;hp=192ed55cf0500c1655fb9b1adba6c3a79512d596;hpb=60174903a7e142bf05586c24498b7e064a7118ff;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 192ed55..d66a188 100644 --- "a/c\316\273ash/CLasH/Normalize.hs" +++ "b/c\316\273ash/CLasH/Normalize.hs" @@ -23,6 +23,7 @@ import qualified UniqSupply import qualified CoreUtils import qualified Type import qualified TcType +import qualified Name import qualified Id import qualified Var import qualified VarSet @@ -220,6 +221,7 @@ letflat (Let (Rec binds) expr) = do -- into a list with just that binding flatbind :: (CoreBndr, CoreExpr) -> TransformMonad [(CoreBndr, CoreExpr)] flatbind (b, Let (Rec binds) expr) = change ((b, expr):binds) + flatbind (b, Let (NonRec b' expr') expr) = change [(b, expr), (b', expr')] flatbind (b, expr) = return [(b, expr)] -- Leave all other expressions unchanged letflat expr = return expr @@ -318,6 +320,37 @@ letmergetop = everywhere ("letmerge", letmerge) inlinenonreptop :: Transform inlinenonreptop = everywhere ("inlinenonrep", inlinebind ((Monad.liftM not) . isRepr . snd)) +inlinetoplevel, inlinetopleveltop :: Transform +-- Any system name is candidate for inlining. Never inline user-defined +-- functions, to preserver structure. +inlinetoplevel expr@(Var f) | (Name.isSystemName . Id.idName) f = do + -- See if this is a top level binding for which we have a body + body_maybe <- Trans.lift $ getGlobalBind f + case body_maybe of + Just body -> do + -- Get the normalized version + norm <- Trans.lift $ getNormalized f + if needsInline norm + then + change norm + else + return expr + -- No body, this is probably a local variable or builtin or external + -- function. + Nothing -> return expr +-- Leave all other expressions unchanged +inlinetoplevel expr = return expr +inlinetopleveltop = everywhere ("inlinetoplevel", inlinetoplevel) + +needsInline :: CoreExpr -> Bool +needsInline expr = case splitNormalized expr of + -- Inline any function that only has a single definition, it is probably + -- simple enough. This might inline some stuff that it shouldn't though it + -- will never inline user-defined functions (inlinetoplevel only tries + -- system names) and inlining should never break things. + (args, [bind], res) -> True + _ -> False + -------------------------------- -- Scrutinee simplification -------------------------------- @@ -608,6 +641,22 @@ funextract expr = return expr -- Perform this transform everywhere funextracttop = everywhere ("funextract", funextract) +-------------------------------- +-- Ensure that a function that just returns another function (or rather, +-- another top-level binder) is still properly normalized. This is a temporary +-- solution, we should probably integrate this pass with lambdasimpl and +-- letsimpl instead. +-------------------------------- +simplrestop expr@(Lam _ _) = return expr +simplrestop expr@(Let _ _) = return expr +simplrestop expr = do + local_var <- Trans.lift $ is_local_var expr + if local_var + then + return expr + else do + id <- Trans.lift $ mkBinderFor expr "res" + change $ Let (NonRec id expr) (Var id) -------------------------------- -- End of transformations -------------------------------- @@ -616,7 +665,7 @@ funextracttop = everywhere ("funextract", funextract) -- What transforms to run? -transforms = [argproptop, funextracttop, etatop, betatop, castproptop, letremovesimpletop, letderectop, letremovetop, letsimpltop, letflattop, scrutsimpltop, casesimpltop, caseremovetop, inlinenonreptop, appsimpltop, letremoveunusedtop, castsimpltop, lambdasimpltop] +transforms = [inlinetopleveltop, argproptop, funextracttop, etatop, betatop, castproptop, letremovesimpletop, letderectop, letremovetop, letsimpltop, letflattop, scrutsimpltop, casesimpltop, caseremovetop, inlinenonreptop, appsimpltop, letremoveunusedtop, castsimpltop, lambdasimpltop, simplrestop] -- | Returns the normalized version of the given function. getNormalized ::