<div>I know that in the case of the prefetch operations they need to be treated like writes so that other operations don't get reordered before / after them. </div><div><br></div><div>For Mvars, concurrency probably comes into play.  Or at least, before we did a readMvar primop it was made out of a take and put, so even through the read prim doesn't write and doesn't block other readers, we still want to treat it's ordering as through it has a write like side effect (Edward yang can probably better opine than I on that one )</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br><div class="gmail_quote"><div>On Fri, Mar 10, 2017 at 5:17 PM David Feuer <<a href="mailto:david@well-typed.com">david@well-typed.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Note [PrimOp can_fail and has_side_effects] in prelude/PrimOp.hs says<br class="gmail_msg">
<br class="gmail_msg">
> A primop "has_side_effects" if it has some *write* effect, visible<br class="gmail_msg">
> elsewhere<br class="gmail_msg">
><br class="gmail_msg">
>     - writing to the world (I/O)<br class="gmail_msg">
>     - writing to a mutable data structure (writeIORef)<br class="gmail_msg">
>     - throwing a synchronous Haskell exception<br class="gmail_msg">
><br class="gmail_msg">
> [...]<br class="gmail_msg">
><br class="gmail_msg">
>  * NB3: *Read* effects (like reading an IORef) don't count here,<br class="gmail_msg">
><br class="gmail_msg">
>    because it doesn't matter if we don't do them, or do them more than<br class="gmail_msg">
>    once.  *Sequencing* is maintained by the data dependency of the state<br class="gmail_msg">
>    token.<br class="gmail_msg">
<br class="gmail_msg">
But this does not actually seem to match what goes on in primops.txt.pp. The<br class="gmail_msg">
following, among many other seemingly read-only operations, have<br class="gmail_msg">
has_side_effects = True:<br class="gmail_msg">
<br class="gmail_msg">
readMutVar# (the very example cited!), readArray#, unsafeFreezeArray#,<br class="gmail_msg">
unsafeThawArray#, tryReadMVar#, deRefWeak#<br class="gmail_msg">
<br class="gmail_msg">
So what's the correct story? Do we want to change the note, or change the<br class="gmail_msg">
reality? The reason I happen to be looking at this is that I think the current<br class="gmail_msg">
arrangement allows us to define unsafeInterleaveIO in a particularly simple<br class="gmail_msg">
fashion:<br class="gmail_msg">
<br class="gmail_msg">
unsafeInterleaveIO = pure . unsafePerformIO<br class="gmail_msg">
<br class="gmail_msg">
but that's only safe as long as the interleaved IO won't float out and get<br class="gmail_msg">
performed before it's forced by normal IO.<br class="gmail_msg">
<br class="gmail_msg">
But the unsafeInterleaveIO story seems much less important, in the grand<br class="gmail_msg">
scheme of things, than making everything else run fast. If indeed it's<br class="gmail_msg">
otherwise safe to mark these read-only ops has_side_effects=False, then I<br class="gmail_msg">
imagine we probably should do that.<br class="gmail_msg">
<br class="gmail_msg">
David Feuer<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
ghc-devs mailing list<br class="gmail_msg">
<a href="mailto:ghc-devs@haskell.org" class="gmail_msg" target="_blank">ghc-devs@haskell.org</a><br class="gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" class="gmail_msg" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br class="gmail_msg">
</blockquote></div></div>