From: Matthijs Kooijman Date: Tue, 6 Apr 2010 14:22:04 +0000 (+0200) Subject: Fix let binding inlining in some cases. X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=0f8a8b4a17081168ca69024d716637b3c42f51bf;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git Fix let binding inlining in some cases. Let binding inlining was not working properly when an to-be-inlined binding used another to-be-inlined binding and they were inlined in the wrong order (the result would be a reference to a no longer existing binding). --- diff --git "a/c\316\273ash/CLasH/Normalize/NormalizeTools.hs" "b/c\316\273ash/CLasH/Normalize/NormalizeTools.hs" index be36349..0f988e0 100644 --- "a/c\316\273ash/CLasH/Normalize/NormalizeTools.hs" +++ "b/c\316\273ash/CLasH/Normalize/NormalizeTools.hs" @@ -120,14 +120,35 @@ inlinebind condition context expr@(Let (Rec binds) res) = do ([], _) -> return expr (replace, others) -> do -- Substitute the to be replaced binders with their expression - newexpr <- Monad.foldM (\e (bndr, repl) -> substitute_clone bndr repl context e) (Let (Rec others) res) replace + newexpr <- do_substitute replace (Let (Rec others) res) change newexpr where + -- Apply the condition to a let binding and return an Either + -- depending on whether it needs to be inlined or not. docond :: (CoreBndr, CoreExpr) -> TransformMonad (Either (CoreBndr, CoreExpr) (CoreBndr, CoreExpr)) docond b = do res <- condition b return $ case res of True -> Left b; False -> Right b + -- Apply the given list of substitutions to the the given expression + do_substitute :: [(CoreBndr, CoreExpr)] -> CoreExpr -> TransformMonad CoreExpr + do_substitute [] expr = return expr + do_substitute ((bndr, val):reps) expr = do + -- Perform this substitution in the expression + expr' <- substitute_clone bndr val context expr + -- And in the substitution values we will be using next + reps' <- mapM (subs_bind bndr val) reps + -- And then perform the remaining substitutions + do_substitute reps' expr' + + -- Replace the given binder with the given expression in the + -- expression oft the given let binding + subs_bind :: CoreBndr -> CoreExpr -> (CoreBndr, CoreExpr) -> TransformMonad (CoreBndr, CoreExpr) + subs_bind bndr expr (b, v) = do + v' <- substitute_clone bndr expr (LetBinding:context) v + return (b, v') + + -- Leave all other expressions unchanged inlinebind _ context expr = return expr