diff --git a/containers/src/Data/IntSet/Internal.hs b/containers/src/Data/IntSet/Internal.hs index df7c04afd..9783da504 100644 --- a/containers/src/Data/IntSet/Internal.hs +++ b/containers/src/Data/IntSet/Internal.hs @@ -1414,6 +1414,16 @@ foldr'Bits :: Int -> (Int -> a -> a) -> a -> Nat -> a {-# INLINE foldr'Bits #-} #if defined(__GLASGOW_HASKELL__) && (WORD_SIZE_IN_BITS==32 || WORD_SIZE_IN_BITS==64) +indexOfTheOnlyBit :: Nat -> Int +{-# INLINE indexOfTheOnlyBit #-} +#if MIN_VERSION_base(4,8,0) && (WORD_SIZE_IN_BITS==64) +indexOfTheOnlyBit bitmask = countTrailingZeros bitmask + +lowestBitSet x = countTrailingZeros x + +highestBitSet x = WORD_SIZE_IN_BITS - 1 - countLeadingZeros x + +#else {---------------------------------------------------------------------- For lowestBitSet we use wordsize-dependant implementation based on multiplication and DeBrujn indeces, which was proposed by Edward Kmett @@ -1427,8 +1437,6 @@ foldr'Bits :: Int -> (Int -> a -> a) -> a -> Nat -> a before changing this code. ----------------------------------------------------------------------} -indexOfTheOnlyBit :: Nat -> Int -{-# INLINE indexOfTheOnlyBit #-} indexOfTheOnlyBit bitmask = I# (lsbArray `indexInt8OffAddr#` unboxInt (intFromNat ((bitmask * magic) `shiftRL` offset))) where unboxInt (I# i) = i @@ -1448,6 +1456,12 @@ indexOfTheOnlyBit bitmask = -- is 48B on 32-bit and 56B on 64-bit architectures -- so the 32B and 64B array -- is actually improvement on 32-bit and only a 8B size increase on 64-bit. +lowestBitSet x = indexOfTheOnlyBit (lowestBitMask x) + +highestBitSet x = indexOfTheOnlyBit (highestBitMask x) + +#endif + lowestBitMask :: Nat -> Nat lowestBitMask x = x .&. negate x {-# INLINE lowestBitMask #-} @@ -1469,10 +1483,6 @@ revNat x1 = case ((x1 `shiftRL` 1) .&. 0x5555555555555555) .|. ((x1 .&. 0x555555 x6 -> ( x6 `shiftRL` 32 ) .|. ( x6 `shiftLL` 32); #endif -lowestBitSet x = indexOfTheOnlyBit (lowestBitMask x) - -highestBitSet x = indexOfTheOnlyBit (highestBitMask x) - foldlBits prefix f z bitmap = go bitmap z where go 0 acc = acc go bm acc = go (bm `xor` bitmask) ((f acc) $! (prefix+bi))