
#9340: Implement new `clz` inline primop -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: feature | Status: new request | Milestone: 7.10.1 Priority: normal | Version: 7.8.2 Component: Compiler | Keywords: primop clz (CodeGen) | Operating System: Unknown/Multiple Resolution: | Type of failure: None/Unknown Differential Revisions: | Test Case: Architecture: | Blocking: Unknown/Multiple | Difficulty: Unknown | Blocked By: | Related Tickets: | -------------------------------------+------------------------------------- Old description:
From a draft for #9281, I had to use a C FFI and using a gcc/clang `__builtin` to get access to the [http://en.wikipedia.org/wiki/Find_first_set CLZ instruction]:
{{{#!hs -- | Compute base-2 log of 'Word#' -- -- This is internally implemented as count-leading-zeros machine instruction. foreign import ccall unsafe "integer_gmp_word_log2" wordLog2# :: Word# -> Int# }}}
{{{#!c HsWord integer_gmp_word_log2(HsWord x) { #if (SIZEOF_HSWORD) == (SIZEOF_INT) return x ? (WORD_SIZE_IN_BITS-1) - __builtin_clz(x) : -1; #elif (SIZEOF_HSWORD) == (SIZEOF_LONG) return x ? (WORD_SIZE_IN_BITS-1) - __builtin_clzl(x) : -1; #elif (SIZEOF_HSWORD) == (SIZEOF_LONG_LONG) return x ? (WORD_SIZE_IN_BITS-1) - __builtin_clzll(x) : -1; #else # error unsupported SIZEOF_HSWORD #endif } }}}
Since a `clz`-like operation should be available on most cpus GHC should expose that as a primop ({{{clz# :: Word# -> Int#}}}).
New description: From a draft for #9281, I had to use a C FFI and using a gcc/clang `__builtin` to get access to the [http://en.wikipedia.org/wiki/Find_first_set CLZ instruction]: {{{#!hs -- | Compute base-2 log of 'Word#' -- -- This is internally implemented as count-leading-zeros machine instruction. foreign import ccall unsafe "integer_gmp_word_log2" wordLog2# :: Word# -> Int# }}} {{{#!c HsWord integer_gmp_word_log2(HsWord x) { #if (SIZEOF_HSWORD) == (SIZEOF_INT) return x ? (WORD_SIZE_IN_BITS-1) - __builtin_clz(x) : -1; #elif (SIZEOF_HSWORD) == (SIZEOF_LONG) return x ? (WORD_SIZE_IN_BITS-1) - __builtin_clzl(x) : -1; #elif (SIZEOF_HSWORD) == (SIZEOF_LONG_LONG) return x ? (WORD_SIZE_IN_BITS-1) - __builtin_clzll(x) : -1; #else # error unsupported SIZEOF_HSWORD #endif } }}} Since a `clz`-like operation should be available on most cpus GHC should expose that as a primop ({{{clz# :: Word# -> Int#}}}). -- Comment (by hvr): (remove hidden Unicode characters in code blocks) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9340#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler