Primops for making exceptions precise or hiding continuation strictness in IO
Currently we consider `raiseIO#` to be the only source of precise exceptions. This is really limiting.
Here are some basic operations we might want to provide:
* `considerExceptionsPrecise#`
* `:: (State# RealWorld -> (# State# RealWorld, a_reppoly #)) -> State# RealWorld -> (# State# RealWorld, a_reppoly #)`
* `considerExceptionsPrecise# a s` is equivalent to `a s` except that when any synchronous exception (precise or imprecise) is raised by the the latter, it becomes a precise exception in the former.
* With our current precise exceptions mechanism, this means that we must hide strictness from the continuation of `considerExceptionsPrecise# a s` unless it can be proven that `a s` does not raise a synchronous exception.
* `hideContinuationStrictness#`
* `:: (State# RealWorld -> (# State# RealWorld, a_reppoly #)) -> State# RealWorld -> (# State# RealWorld, a_reppoly #)`
* At runtime, `hideContinuationStrictness# a s` is equivalent to `a s`. But `case hideContinuationStrictness# a s of (# s', r #) -> cont #)` is _lazy_ in `cont`. This is similar in effect to our precise exceptions mechanism, but is not tied to whether the action `a s` throws an exception.
* Or perhaps we could instead use `evalBarrier# :: State# RealWorld -> State# RealWorld` and define `hideContinuationStrictness# a s = case considerExceptionsPrecise# a s of (# s2, r #) -> case evalBarrier# s2 of s3 -> (# s3, r #)`. (The `considerExceptionsPrecise#` here is not optional: If `a s` diverges we will drop the `evalBarrier#` in the continuation. We can consider an exception to be precise iff it includes an eval barrier.)
issue