|
|
# Implementing new primitive comparisons to allow branchless algorithms
|
|
|
|
|
|
|
|
|
This page presents motivation and technical details behind implementing new primitive comparison operators (this was originaly reported as Trac ticket [\#6135](https://gitlab.haskell.org/ghc/ghc/issues/6135)). See [this page](http://ghc.haskell.org/trac/ghc/wiki/NewPrimopsInGHC7.8) for instructions how to adjust your already existing code to work with new primops.
|
|
|
This page presents motivation and technical details behind implementing new primitive comparison operators (this was originaly reported as Trac ticket #6135). See [this page](http://ghc.haskell.org/trac/ghc/wiki/NewPrimopsInGHC7.8) for instructions how to adjust your already existing code to work with new primops.
|
|
|
|
|
|
|
|
|
See also
|
|
|
|
|
|
|
|
|
- [\#9661](https://gitlab.haskell.org/ghc/ghc/issues/9661)
|
|
|
- [\#13397](https://gitlab.haskell.org/ghc/ghc/issues/13397)
|
|
|
- #9661
|
|
|
- #13397
|
|
|
|
|
|
## The problem
|
|
|
|
... | ... | @@ -251,9 +251,9 @@ Below is a summary of implementation details and decisions: |
|
|
|
|
|
- The new comparison primops return a value of type `Int#`: `1#` represents `True` and `0#` represents `False`. The `Int#` type was chosen because in Haskell it is more common to use signed `Int` type insetad of unsigned `Word`. By using `Int#` the users can easily convert unboxed result into a boxed value, without need to use `word2Int#` and `int2word#` primops.
|
|
|
|
|
|
- Unlike C, `2#` or `-3#` don't represent a Boolean value. More concretely, you can use `tagToEnum#` to convert one of these `Int#` values to a `Bool`, but `tagToEnum#` does no error checking, so it would be Very Very Bad to call it on `2#`. Our plan is to provide safe `isTrue#` and `isFalse#` functions, which will check whether its `Int#` parameter is a valid representation of `True` (i.e. it is `1#`) or `False` (i.e. it is `0#`). This is not possible at the moment due to deficiency in the code generator (see [\#8326](https://gitlab.haskell.org/ghc/ghc/issues/8326)), but we do provide `isTrue#` function for you to use (defined in `GHC.Types`, re-exported by `GHC.Base` and `GHC.Exts`). Currently it is an alias to `tagToEnum#` and is therefore unsafe, but once we solve [\#8326](https://gitlab.haskell.org/ghc/ghc/issues/8326) we will turn it into a safe function.
|
|
|
- Unlike C, `2#` or `-3#` don't represent a Boolean value. More concretely, you can use `tagToEnum#` to convert one of these `Int#` values to a `Bool`, but `tagToEnum#` does no error checking, so it would be Very Very Bad to call it on `2#`. Our plan is to provide safe `isTrue#` and `isFalse#` functions, which will check whether its `Int#` parameter is a valid representation of `True` (i.e. it is `1#`) or `False` (i.e. it is `0#`). This is not possible at the moment due to deficiency in the code generator (see #8326), but we do provide `isTrue#` function for you to use (defined in `GHC.Types`, re-exported by `GHC.Base` and `GHC.Exts`). Currently it is an alias to `tagToEnum#` and is therefore unsafe, but once we solve #8326 we will turn it into a safe function.
|
|
|
|
|
|
- As a small side-task, four new logical bitwise primops have been implemented: `andI#`, `orI#`, `xorI#` and `negI#` ([\#7689](https://gitlab.haskell.org/ghc/ghc/issues/7689)). These operate on values of type `Int#`. Earlier we only had bitwise logical primops operating on values of type `Word#`.
|
|
|
- As a small side-task, four new logical bitwise primops have been implemented: `andI#`, `orI#`, `xorI#` and `negI#` (#7689). These operate on values of type `Int#`. Earlier we only had bitwise logical primops operating on values of type `Word#`.
|
|
|
|
|
|
- Functions for comparing values of `Integer` type are not primops from technical point of view, because they are implemented in Haskell (in case of integer-gmp also with FFI), but they pretend to be ones. There are six primops for comparing `Integer` values:
|
|
|
|
... | ... | @@ -271,7 +271,7 @@ Each of these functions has a wrapper that calls `isTrue#` and returns a `Bool`. |
|
|
|
|
|
- Other libraries that were modified to work with the new primops are: array, base, dph, ghc-prim, primitive and template-haskell.
|
|
|
|
|
|
- GHC received an internal module [compiler/utils/ExtsCompat46](/trac/ghc/browser/ghc/compiler/utils/ExtsCompat46) that allows to bootstrap with GHC versions that have old primops (i.e. GHC 7.6 and GHC 7.4). This module is meant to be temporary - see [\#8330](https://gitlab.haskell.org/ghc/ghc/issues/8330).
|
|
|
- GHC received an internal module [compiler/utils/ExtsCompat46](/trac/ghc/browser/ghc/compiler/utils/ExtsCompat46) that allows to bootstrap with GHC versions that have old primops (i.e. GHC 7.6 and GHC 7.4). This module is meant to be temporary - see #8330.
|
|
|
|
|
|
### Benchmarks
|
|
|
|
... | ... | |