Fix let binding inlining in some cases.
authorMatthijs Kooijman <matthijs@stdin.nl>
Tue, 6 Apr 2010 14:22:04 +0000 (16:22 +0200)
committerMatthijs Kooijman <matthijs@stdin.nl>
Tue, 6 Apr 2010 14:22:04 +0000 (16:22 +0200)
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).

cλash/CLasH/Normalize/NormalizeTools.hs

index be36349f0f2bed459449a941a9ee6c1cb2810755..0f988e02a598ec314b3a4dee57dac3e339eac4d8 100644 (file)
@@ -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