summaryrefslogtreecommitdiff
path: root/compiler/utils/FastBool.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils/FastBool.hs')
-rw-r--r--compiler/utils/FastBool.hs70
1 files changed, 70 insertions, 0 deletions
diff --git a/compiler/utils/FastBool.hs b/compiler/utils/FastBool.hs
new file mode 100644
index 0000000000..9e88376f0a
--- /dev/null
+++ b/compiler/utils/FastBool.hs
@@ -0,0 +1,70 @@
+{-
+(c) The University of Glasgow, 2000-2006
+
+\section{Fast booleans}
+-}
+
+{-# LANGUAGE CPP, MagicHash #-}
+
+module FastBool (
+ --fastBool could be called bBox; isFastTrue, bUnbox; but they're not
+ FastBool, fastBool, isFastTrue, fastOr, fastAnd
+ ) where
+
+-- Import the beggars
+import GHC.Exts
+#ifdef DEBUG
+import Panic
+#endif
+
+type FastBool = Int#
+fastBool True = 1#
+fastBool False = 0#
+
+#ifdef DEBUG
+--then waste time deciding whether to panic. FastBool should normally
+--be at least as fast as Bool, one would hope...
+
+isFastTrue 1# = True
+isFastTrue 0# = False
+isFastTrue _ = panic "FastTypes: isFastTrue"
+
+-- note that fastOr and fastAnd are strict in both arguments
+-- since they are unboxed
+fastOr 1# _ = 1#
+fastOr 0# x = x
+fastOr _ _ = panicFastInt "FastTypes: fastOr"
+
+fastAnd 0# _ = 0#
+fastAnd 1# x = x
+fastAnd _ _ = panicFastInt "FastTypes: fastAnd"
+
+--these "panicFastInt"s (formerly known as "panic#") rely on
+--FastInt = FastBool ( = Int# presumably),
+--haha, true enough when __GLASGOW_HASKELL__. Why can't we have functions
+--that return _|_ be kind-polymorphic ( ?? to be precise ) ?
+
+#else /* ! DEBUG */
+--Isn't comparison to zero sometimes faster on CPUs than comparison to 1?
+-- (since using Int# as _synonym_ fails to guarantee that it will
+-- only take on values of 0 and 1)
+isFastTrue 0# = False
+isFastTrue _ = True
+
+-- note that fastOr and fastAnd are strict in both arguments
+-- since they are unboxed
+-- Also, to avoid incomplete-pattern warning
+-- (and avoid wasting time with redundant runtime checks),
+-- we don't pattern-match on both 0# and 1# .
+fastOr 0# x = x
+fastOr _ _ = 1#
+
+fastAnd 0# _ = 0#
+fastAnd _ x = x
+
+#endif /* ! DEBUG */
+
+fastBool :: Bool -> FastBool
+isFastTrue :: FastBool -> Bool
+fastOr :: FastBool -> FastBool -> FastBool
+fastAnd :: FastBool -> FastBool -> FastBool