clash-lang / clash-compiler

Haskell to VHDL/Verilog/SystemVerilog compiler
https://clash-lang.org/
Other
1.4k stars 147 forks source link

No evaluator support for `throw` #2158

Open christiaanb opened 2 years ago

christiaanb commented 2 years ago

Something that just occurs to me: since errorX is just throw (XException ...) it presumably always gets left alone by the simplifier, but what if a user writes throw (XException "Boom") directly? Does this then fail to be identified as an undefined X primitive and get identified as a normal undefined primitive?

_Originally posted by @alex-mckenna in https://github.com/clash-lang/clash-compiler/pull/2153#discussion_r841422887_

It is "left alone" by the evaluator because there's no evaluator rule for throw, meaning any expression where the result of throw is forced, the evaluator collapses to Nothing.

When/if we ever do get to implement the evaluator rule for throw, we should probably evaluate to a Clash.Normalize.Primitive.undefinedX value when an XException is thrown, and Clash.Normalize.Primitive.undefined otherwise.

mheinzel commented 1 year ago

I'd like to work on this. @alex-mckenna already gave me some pointers for where to look and how to write a test case for it.

For reference, we were also a bit surprised that errorX does not have a NOINLINE pragma (which wouldn't avoid this issue in general, but might still be a good idea?).

christiaanb commented 1 year ago

For reference, we were also a bit surprised that errorX does not have a NOINLINE pragma (which wouldn't avoid this issue in general, but might still be a good idea?).

That's bottoming values never get an unfolding in the interface file, so it's implicitly NOINLINE across modules; see also https://github.com/clash-lang/clash-compiler/commit/e5faf05d3cce867d1f4a0f58a15901455d9062f3

alex-mckenna commented 1 year ago

Ah, I forgot we checked for bottoming in clash-ghc. This all makes sense now