Unboxed Booleans
Right now the only way to compare two integers is with primops that produce boxed bools:
<# :: Int# -> Int# -> Bool
==# :: Int# -> Int# -> Bool
To consume the resulting Bool
we need a case-expression, which introduces branches into the core IR and object code. Case expressions are bad in the presence of heavy inlining because case-of-case performed by the GHC simplifier tends to duplicate code (like in DPH and Repa programs). Mis-predicted branches are bad in object code because they stall the pipeline.
Consider the following expression:
case x <# 0# || x >=# aWidth
|| y <# 0# || y >=# aHeight of
True -> ...
False -> ...
This is very common in array programming. Ideally, it should turn into some straight-line code to compute the flag, and then a single branch instruction once we've worked out what alternative to take. However, as the only way to consume the Bool
s produced by the comparisons is to introduce more case expressions, we end up with *four* cases in the core IR.
What I want is this:
data Bool#
(.<#) :: Int# -> Int# -> Bool#
(.==#) :: Int# -> Int# -> Bool#
(.||#) :: Bool# -> Bool# -> Bool#
case x .<# 0# .||# x .>=# aWidth
.||# y .<# 0# .||# y .>=# aHeight of
True# -> ...
False# -> ...
Bool# is the type of one bit integers. I can compute with them algebraically and be sure that I'll get at most one branch instruction in the resulting object code.