From: Jose Pedro Magalhaes Date: Mon, 2 May 2011 19:13:19 +0000 (+0200) Subject: Merge branch 'master' of http://darcs.haskell.org/packages/base into ghc-generics X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=e95046ebf2e4833b56c6ddaf5b3108390cee08a5;p=ghc-base.git Merge branch 'master' of darcs.haskell.org/packages/base into ghc-generics Solved conflicts: GHC/Int.hs --- e95046ebf2e4833b56c6ddaf5b3108390cee08a5 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. + -} -