Skip to content

Commit 8ee95b9

Browse files
committed
Don't inline function bodies with Synthesize ANN
This will duplicate Clash compiler work even though the user indicated that they want to make use of the Clash compiler's caching capabilities by giving the function a Synthesize annotation. Fixes #3024
1 parent 2c9b934 commit 8ee95b9

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FIXED: Clash will no longer ignore Synthesize annotations when the function is used in an argument position [#3024](https://github.com/clash-lang/clash-compiler/issues/3024)

clash-lib/src/Clash/Normalize/Transformations/Specialize.hs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,11 +475,18 @@ specialize' (TransformContext is0 _) e (Var f, args, ticks) specArgIn = do
475475
-- g | g
476476
-- !f and !g | f_g
477477
--
478+
-- Finally, we must make sure we do not inline the bodies
479+
-- of functions with a Synthesize annotation, as that would
480+
-- duplicate Clash compiler work. See also issue #3024
478481
gTmM <- fmap (UniqMap.lookup g) $ Lens.use bindings
482+
let gBody = if g `elemVarSet` topEnts then
483+
Nothing
484+
else
485+
fmap bindingTerm gTmM
479486
return
480487
( specializeName (inl, varName f) (bindingSpec <$> gTmM, varName g)
481488
, preferNoInline inl (maybe noUserInline bindingSpec gTmM)
482-
, maybe specArg (Left . (`mkApps` gArgs) . bindingTerm) gTmM
489+
, maybe specArg (Left . (`mkApps` gArgs)) gBody
483490
)
484491
else return (varName f, inl, specArg)
485492
_ -> return (varName f, inl, specArg)

tests/Main.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,7 @@ runClashTest = defaultMain
907907
, outputTest "Simple" def
908908
, outputTest "T1771" def
909909
, runTest "Product" def
910+
, outputTest "T3024" def{hdlTargets=[VHDL], hdlLoad = [], hdlSim = []}
910911
]
911912
, clashTestGroup "Testbench"
912913
[ runTest "TB" def{clashFlags=["-fclash-inline-limit=0"]}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{-# LANGUAGE CPP #-}
2+
module T3024 where
3+
4+
import qualified Prelude as P
5+
6+
import qualified Data.List as List
7+
import System.Environment (getArgs)
8+
import System.FilePath ((</>), takeDirectory)
9+
10+
import Clash.Prelude
11+
import Clash.Annotations.TopEntity
12+
13+
f :: Unsigned 8 -> Unsigned 8
14+
f x = x + 1
15+
{-# ANN f (Synthesize {t_name = "f", t_inputs = [PortName "x"], t_output = PortName "y"}) #-}
16+
{-# CLASH_OPAQUE f #-}
17+
18+
g :: (Unsigned 8 -> Unsigned 8) -> Unsigned 8 -> Unsigned 8
19+
g h x = (h x + h (x * 8))
20+
{-# CLASH_OPAQUE g #-}
21+
22+
q :: Unsigned 8 -> Unsigned 8
23+
q = g f
24+
{-# ANN q (Synthesize {t_name = "q", t_inputs = [PortName "a"], t_output = PortName "b"}) #-}
25+
{-# CLASH_OPAQUE q #-}
26+
27+
assertIn :: String -> String -> IO ()
28+
assertIn needle haystack
29+
| List.isInfixOf needle haystack = pure ()
30+
| otherwise = P.error $ mconcat
31+
[ "Expected:\n\n ", needle, "\n\nIn:\n\n", haystack]
32+
33+
mainVHDL :: IO ()
34+
mainVHDL = do
35+
[topDir] <- getArgs
36+
content <- readFile (topDir </> show 'q </> "T3024_q_g_f.vhdl")
37+
38+
assertIn "entity f.f" content

0 commit comments

Comments
 (0)