The following reduced test-case:
import Clash.Prelude
incr :: Index 2 -> Index 2
incr i = if i == maxBound then 0 else i + 1
{-# NOINLINE incr #-}
topEntity :: Index 10 -> Index 2
topEntity j = case j < 1 of
False ->
let xs = init (Cons 1 (Cons (incr (head xs)) Nil)) in last xs
True ->
let ys = init (Cons 2 (Cons (incr (last ys)) Nil)) in head ys
throws the DEC transformation into a loop. Specifically, DEC rewrites:
case j < 1 of
False ->
let xs = init (Cons 1 (Cons (incr (head xs)) Nil)) in last xs
True ->
let ys = init (Cons 2 (Cons (incr (last ys)) Nil)) in head ys
to
let incrOut = incr (case j < 1 of
False ->
let xs = init (Cons 1 (Cons (incr (head xs)) Nil)) in head xs
True ->
let ys = init (Cons 2 (Cons (incr (last ys)) Nil)) in last ys)
in case j < 1 of
False ->
let xs = init (Cons 1 (Cons incrOut Nil)) in last xs
True ->
let ys = init (Cons 2 (Cons incrOut Nil)) in head ys
trying to share uses of incr between the two case-alternatives; only to create a new case-expression on which DEC can match again. What DEC should be doing is rewrite to:
let incrOut = incr (case j < 1 of
False ->
let xs = init (Cons 1 (Cons incrOut Nil)) in head xs
True ->
let ys = init (Cons 2 (Cons incrOut Nil)) in last ys)
in case j < 1 of
False ->
let xs = init (Cons 1 (Cons incrOut Nil)) in last xs
True ->
let ys = init (Cons 2 (Cons incrOut Nil)) in head ys
The following reduced test-case:
throws the DEC transformation into a loop. Specifically, DEC rewrites:
to
trying to share uses of
incrbetween the two case-alternatives; only to create a new case-expression on which DEC can match again. What DEC should be doing is rewrite to: