Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Register
  • Sign in
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
    • Locked files
  • Issues 5.5k
    • Issues 5.5k
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 634
    • Merge requests 634
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Artifacts
    • Schedules
    • Test cases
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Model experiments
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #6135

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 Bools 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.

Edited Mar 10, 2019 by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking