diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2021-03-31 15:31:19 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-04-09 03:31:02 -0400 |
commit | c02ac1bbd2d882d58307fa3009aa2d9665399703 (patch) | |
tree | 0c5a038ca509a36e4b24ceca3643d65e63a7e533 /compiler/GHC/Prelude.hs | |
parent | 0bdb867e37bcfe4ae2c5c4f5f7e54b41acfe6116 (diff) | |
download | haskell-c02ac1bbd2d882d58307fa3009aa2d9665399703.tar.gz |
Re-export GHC.Bits from GHC.Prelude with custom shift implementation.
This allows us to use the unsafe shifts in non-debug builds for performance.
For older versions of base we instead export Data.Bits
See also #19618
Diffstat (limited to 'compiler/GHC/Prelude.hs')
-rw-r--r-- | compiler/GHC/Prelude.hs | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/compiler/GHC/Prelude.hs b/compiler/GHC/Prelude.hs index 95c2d4b190..d538adfefb 100644 --- a/compiler/GHC/Prelude.hs +++ b/compiler/GHC/Prelude.hs @@ -10,15 +10,17 @@ -- * Is compiled with -XNoImplicitPrelude -- * Explicitly imports GHC.Prelude -module GHC.Prelude (module X) where +module GHC.Prelude + (module X + ,module Bits + ,shiftL, shiftR + ) where + -- We export the 'Semigroup' class but w/o the (<>) operator to avoid -- clashing with the (Outputable.<>) operator which is heavily used -- through GHC's code-base. -import Prelude as X hiding ((<>)) -import Data.Foldable as X (foldl') - {- Note [Why do we import Prelude here?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -31,3 +33,56 @@ NoImplicitPrelude. There are two motivations for this: giving a smoother development experience when adding new extensions. -} + +import Prelude as X hiding ((<>)) +import Data.Foldable as X (foldl') + +#if MIN_VERSION_base(4,15,0) +import GHC.Bits as Bits hiding (shiftL, shiftR) +# if defined(DEBUG) +import qualified GHC.Bits as Bits (shiftL, shiftR) +# endif + +#else +--base <4.15 +import Data.Bits as Bits hiding (shiftL, shiftR) +# if defined(DEBUG) +import qualified Data.Bits as Bits (shiftL, shiftR) +# endif +#endif + +{- Note [Default to unsafe shifts inside GHC] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The safe shifts can introduce branches which come +at the cost of performance. We still want the additional +debugability for debug builds. So we define it as one or the +other depending on the DEBUG setting. + +Why do we then continue on to re-export the rest of Data.Bits? +If we would not what is likely to happen is: +* Someone imports Data.Bits, uses xor. Things are fine. +* They add a shift and get an ambigious definition error. +* The are puzzled for a bit. +* They either: + + Remove the import of Data.Bits and get an error because xor is not in scope. + + Add the hiding clause to the Data.Bits import for the shifts. + +Either is quite annoying. Simply re-exporting all of Data.Bits avoids this +making for a smoother developer experience. At the cost of having a few more +names in scope at all time. But that seems like a fair tradeoff. + +See also #19618 +-} + +-- We always want the Data.Bits method to show up for rules etc. +{-# INLINE shiftL #-} +{-# INLINE shiftR #-} +shiftL, shiftR :: Bits.Bits a => a -> Int -> a +#if defined(DEBUG) +shiftL = Bits.shiftL +shiftR = Bits.shiftR +#else +shiftL = Bits.unsafeShiftL +shiftR = Bits.unsafeShiftR +#endif + |