Tweak the small integer case of gcdInteger for better optimisation
authorDuncan Coutts <duncan@well-typed.com>
Sat, 13 Jun 2009 13:40:49 +0000 (13:40 +0000)
committerDuncan Coutts <duncan@well-typed.com>
Sat, 13 Jun 2009 13:40:49 +0000 (13:40 +0000)
The gcdInt function in the base package now calls gcdInteger with
two small integers. With this weak, the optimiser generates a base
gcdInt that directly calls the gcdInt# primop from this package.
This means there should be no additional overhead compared to when
the base gcdInt called the gcdInt# primop directly.

GHC/Integer.lhs

index 07f8905..4d32d76 100644 (file)
@@ -261,13 +261,6 @@ gcdInteger :: Integer -> Integer -> Integer
 gcdInteger a@(S# INT_MINBOUND) b = gcdInteger (toBig a) b
 gcdInteger a b@(S# INT_MINBOUND) = gcdInteger a (toBig b)
 gcdInteger (S# a) (S# b) = S# (gcdInt a b)
-    where -- XXX Copied from GHC.Base
-          gcdInt :: Int# -> Int# -> Int#
-          gcdInt 0# y  = absInt y
-          gcdInt x  0# = absInt x
-          gcdInt x  y  = gcdInt# (absInt x) (absInt y)
-
-          absInt x = if x <# 0# then negateInt# x else x
 gcdInteger ia@(S# a)  ib@(J# sb b)
  =      if a  ==# 0# then absInteger ib
    else if sb ==# 0# then absInteger ia
@@ -285,6 +278,17 @@ lcmInteger a b =      if a `eqInteger` S# 0# then S# 0#
   where aa = absInteger a
         ab = absInteger b
 
+{-# RULES "gcdInteger/Int" forall a b.
+            gcdInteger (S# a) (S# b) = S# (gcdInt a b)
+  #-}
+gcdInt :: Int# -> Int# -> Int#
+gcdInt 0# y  = absInt y
+gcdInt x  0# = absInt x
+gcdInt x  y  = gcdInt# (absInt x) (absInt y)
+
+absInt :: Int# -> Int#
+absInt x = if x <# 0# then negateInt# x else x
+
 divExact :: Integer -> Integer -> Integer
 divExact a@(S# INT_MINBOUND) b = divExact (toBig a) b
 divExact (S# a) (S# b) = S# (quotInt# a b)