Repository : ssh://darcs.haskell.org//srv/darcs/packages/base

On branch  : ghc-generics

http://hackage.haskell.org/trac/ghc/changeset/e95046ebf2e4833b56c6ddaf5b3108390cee08a5

>---------------------------------------------------------------

commit e95046ebf2e4833b56c6ddaf5b3108390cee08a5
Merge: 4817fca... a07504a...
Author: Jose Pedro Magalhaes <[email protected]>
Date:   Mon May 2 21:13:19 2011 +0200

    Merge branch 'master' of http://darcs.haskell.org/packages/base into 
ghc-generics
    
    Solved conflicts:
        GHC/Int.hs

 GHC/Event.hs        |    2 +
 GHC/Event/Thread.hs |   19 ++++--
 GHC/Int.hs          |  196 +++++++++++++++++++++++++++++++++++++++++---------
 GHC/Real.lhs        |   18 +++--
 4 files changed, 187 insertions(+), 48 deletions(-)

diff --cc GHC/Int.hs
index 8e8264a,7a42bb3..146bf66
--- a/GHC/Int.hs
+++ b/GHC/Int.hs
@@@ -911,26 -908,127 +911,150 @@@ instance Ix Int64 wher
      unsafeIndex (m,_) i = fromIntegral i - fromIntegral m
      inRange (m,n) i     = m <= i && i <= n
  
 +------------------------------------------------------------------------
 +-- Generic deriving
 +------------------------------------------------------------------------
 +
 +-- We need instances for some basic datatypes, but some of those use Int,
 +-- so we have to put the instances here
 +{-
 +deriving instance Eq Arity
 +deriving instance Eq Associativity
 +deriving instance Eq Fixity
 +
 +deriving instance Ord Arity
 +deriving instance Ord Associativity
 +deriving instance Ord Fixity
 +
 +deriving instance Read Arity
 +deriving instance Read Associativity
 +deriving instance Read Fixity
 +
 +deriving instance Show Arity
 +deriving instance Show Associativity
 +deriving instance Show Fixity
 +-}
++
+ {-
+ Note [Order of tests]
+ 
+ Suppose we had a definition like:
+ 
+     quot x y
+      | y == 0                     = divZeroError
+      | x == minBound && y == (-1) = overflowError
+      | otherwise                  = x `primQuot` y
+ 
+ Note in particular that the
+     x == minBound
+ test comes before the
+     y == (-1)
+ test.
+ 
+ this expands to something like:
+ 
+     case y of
+     0 -> divZeroError
+     _ -> case x of
+          -9223372036854775808 ->
+              case y of
+              -1 -> overflowError
+              _ -> x `primQuot` y
+          _ -> x `primQuot` y
+ 
+ Now if we have the call (x `quot` 2), and quot gets inlined, then we get:
+ 
+     case 2 of
+     0 -> divZeroError
+     _ -> case x of
+          -9223372036854775808 ->
+              case 2 of
+              -1 -> overflowError
+              _ -> x `primQuot` 2
+          _ -> x `primQuot` 2
+ 
+ which simplifies to:
+ 
+     case x of
+     -9223372036854775808 -> x `primQuot` 2
+     _                    -> x `primQuot` 2
+ 
+ Now we have a case with two identical branches, which would be
+ eliminated (assuming it doesn't affect strictness, which it doesn't in
+ this case), leaving the desired:
+ 
+     x `primQuot` 2
+ 
+ except in the minBound branch we know what x is, and GHC cleverly does
+ the division at compile time, giving:
+ 
+     case x of
+     -9223372036854775808 -> -4611686018427387904
+     _                    -> x `primQuot` 2
+ 
+ So instead we use a definition like:
+ 
+     quot x y
+      | y == 0                     = divZeroError
+      | y == (-1) && x == minBound = overflowError
+      | otherwise                  = x `primQuot` y
+ 
+ which gives us:
+ 
+     case y of
+     0 -> divZeroError
+     -1 ->
+         case x of
+         -9223372036854775808 -> overflowError
+         _ -> x `primQuot` y
+     _ -> x `primQuot` y
+ 
+ for which our call (x `quot` 2) expands to:
+ 
+     case 2 of
+     0 -> divZeroError
+     -1 ->
+         case x of
+         -9223372036854775808 -> overflowError
+         _ -> x `primQuot` 2
+     _ -> x `primQuot` 2
+ 
+ which simplifies to:
+ 
+     x `primQuot` 2
+ 
+ as required.
+ 
+ 
+ 
+ But we now have the same problem with a constant numerator: the call
+ (2 `quot` y) expands to
+ 
+     case y of
+     0 -> divZeroError
+     -1 ->
+         case 2 of
+         -9223372036854775808 -> overflowError
+         _ -> 2 `primQuot` y
+     _ -> 2 `primQuot` y
+ 
+ which simplifies to:
+ 
+     case y of
+     0 -> divZeroError
+     -1 -> 2 `primQuot` y
+     _ -> 2 `primQuot` y
+ 
+ which simplifies to:
+ 
+     case y of
+     0 -> divZeroError
+     -1 -> -2
+     _ -> 2 `primQuot` y
+ 
+ 
+ However, constant denominators are more common than constant numerators,
+ so the
+     y == (-1) && x == minBound
+ order gives us better code in the common case.
+ -}
 -



_______________________________________________
Cvs-libraries mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-libraries

Reply via email to