Ticket #5122: logarithms-integer-gmp-and-haddock-fix.dpatch

File logarithms-integer-gmp-and-haddock-fix.dpatch, 14.0 KB (added by daniel.is.fischer, 2 years ago)

darcs patch for integer-gmp

Line 
12 patches for repository /home/dafis/Haskell/Hacking/ghc/libraries/integer-gmp:
2
3Wed Mar 30 18:18:52 CEST 2011  Daniel Fischer <daniel.is.fischer@googlemail.com>
4  * Integer logarithms
5  Added modules for fast calculation of integer logarithms needed for fromRational.
6
7Thu Mar 31 01:17:10 CEST 2011  Daniel Fischer <daniel.is.fischer@googlemail.com>
8  * Fix Haddock markup
9
10New patches:
11
12[Integer logarithms
13Daniel Fischer <daniel.is.fischer@googlemail.com>**20110330161852
14 Ignore-this: 1942dbd5378c70da60f79bb3b49fcb37
15] {
16adddir ./GHC/Integer/Logarithms
17addfile ./GHC/Integer/Logarithms.hs
18hunk ./GHC/Integer/Logarithms.hs 1
19+{-# LANGUAGE MagicHash, UnboxedTuples, NoImplicitPrelude #-}
20+module GHC.Integer.Logarithms
21+    ( integerLogBase#
22+    , integerLog2#
23+    , wordLog2#
24+    ) where
25+
26+import GHC.Prim
27+import GHC.Integer
28+import qualified GHC.Integer.Logarithms.Internals as I
29+
30+-- | Calculate the integer logarithm for an arbitrary base.
31+--   The base must be greater than 1, the second argument, the number
32+--   whose logarithm is sought, should be positive, otherwise the
33+--   result is meaningless.
34+--
35+-- >
36+--   base ^ integerLogBase# base m <= m < base ^ (integerLogBase# base m + 1)
37+-- >
38+--
39+-- for @base > 1@ and @m > 0@.
40+integerLogBase# :: Integer -> Integer -> Int#
41+integerLogBase# b m = case step b of
42+                        (# _, e #) -> e
43+  where
44+    step pw =
45+      if m `ltInteger` pw
46+        then (# m, 0# #)
47+        else case step (pw `timesInteger` pw) of
48+               (# q, e #) ->
49+                 if q `ltInteger` pw
50+                   then (# q, 2# *# e #)
51+                   else (# q `quotInteger` pw, 2# *# e +# 1# #)
52+
53+-- | Calculate the integer base 2 logarithm of an 'Integer'.
54+--   The calculation is more efficient than for the general case,
55+--   on platforms with 32- or 64-bit words much more efficient.
56+--
57+--  The argument must be strictly positive, that condition is /not/ checked.
58+integerLog2# :: Integer -> Int#
59+integerLog2# = I.integerLog2#
60+
61+-- | This function calculates the integer base 2 logarithm of a 'Word#'.
62+wordLog2# :: Word# -> Int#
63+wordLog2# = I.wordLog2#
64addfile ./GHC/Integer/Logarithms/Internals.hs
65hunk ./GHC/Integer/Logarithms/Internals.hs 1
66+{-# LANGUAGE CPP, MagicHash, UnboxedTuples, NoImplicitPrelude #-}
67+{-# OPTIONS_HADDOCK hide #-}
68+
69+#include "MachDeps.h"
70+
71+-- Fast integer logarithms to base 2.
72+-- integerLog2# and wordLog2# are of general usefulness,
73+-- the others are only needed for a fast implementation of
74+-- fromRational.
75+-- Since they are needed in GHC.Float, we must expose this
76+-- module, but it should not show up in the docs.
77+
78+module GHC.Integer.Logarithms.Internals
79+    ( integerLog2#
80+    , integerLog2IsPowerOf2#
81+    , wordLog2#
82+    , roundingMode#
83+    ) where
84+
85+import GHC.Prim
86+import GHC.Integer.Type
87+
88+-- When larger word sizes become common, add support for those,
89+-- it is not hard, just tedious.
90+#if (WORD_SIZE_IN_BITS != 32) && (WORD_SIZE_IN_BITS != 64)
91+
92+-- Less than ideal implementations for strange word sizes
93+
94+import GHC.Integer
95+
96+default ()
97+
98+-- We do not know whether the word has 30 bits or 128 or even more,
99+-- so we cannot start from the top, although that would be much more
100+-- efficient.
101+-- Count the bits until the highest set bit is found.
102+wordLog2# :: Word# -> Int#
103+wordLog2# w = go 8# w
104+  where
105+    go acc u = case u `uncheckedShiftRL#` 8# of
106+                0## -> case leadingZeros of
107+                        BA ba -> acc -# indexInt8Array# ba (word2Int# u)
108+                v   -> go (acc +# 8#) v
109+
110+-- Assumption: Integer is strictly positive
111+integerLog2# :: Integer -> Int#
112+integerLog2# (S# i) = wordLog2# (int2Word# i) -- that is easy
113+integerLog2# m = case step m (smallInteger 2#) 1# of
114+                    (# _, l #) -> l
115+  where
116+    -- Invariants:
117+    -- pw = 2 ^ lg
118+    -- case step n pw lg of
119+    --   (q, e) -> pw^(2*e) <= n < pw^(2*e+2)
120+    --              && q <= n/pw^(2*e) < (q+1)
121+    --              && q < pw^2
122+    step n pw lg =
123+      if n `ltInteger` pw
124+        then (# n, 0# #)
125+        else case step n (shiftLInteger pw lg) (2# *# lg) of
126+              (# q, e #) ->
127+                if q `ltInteger` pw
128+                  then (# q, 2# *# e #)
129+                  else (# q `shiftRInteger` lg, 2# *# e +# 1# #)
130+
131+-- Calculate the log2 of a positive integer and check
132+-- whether it is a power of 2.
133+-- By coincidence, the presence of a power of 2 is
134+-- signalled by zero and not one.
135+integerLog2IsPowerOf2# :: Integer -> (# Int#, Int# #)
136+integerLog2IsPowerOf2# m =
137+    case integerLog2# m of
138+      lg -> if m `eqInteger` (smallInteger 1# `shiftLInteger` lg)
139+              then (# lg, 0# #)
140+              else (# lg, 1# #)
141+
142+-- Detect the rounding mode,
143+-- 0# means round to zero,
144+-- 1# means round to even,
145+-- 2# means round away from zero
146+roundingMode# :: Integer -> Int# -> Int#
147+roundingMode# m h =
148+    case smallInteger 1# `shiftLInteger` h of
149+      c -> case m `andInteger`
150+                ((c `plusInteger` c) `minusInteger` smallInteger 1#) of
151+             r ->
152+               if c `ltInteger` r
153+                 then 2#
154+                 else if c `gtInteger` r
155+                        then 0#
156+                        else 1#
157+
158+#else
159+
160+default ()
161+
162+-- We have a nice word size, we can do much better now.
163+
164+#if WORD_SIZE_IN_BITS == 32
165+
166+#define WSHIFT 5
167+#define MMASK 31
168+
169+#else
170+
171+#define WSHIFT 6
172+#define MMASK 63
173+
174+#endif
175+
176+-- Assumption: Integer is strictly positive
177+-- For small integers, use wordLog#,
178+-- in the general case, check words from the most
179+-- significant down, once a nonzero word is found,
180+-- calculate its log2 and add the number of following bits.
181+integerLog2# :: Integer -> Int#
182+integerLog2# (S# i) = wordLog2# (int2Word# i)
183+integerLog2# (J# s ba) = check (s -# 1#)
184+  where
185+    check i = case indexWordArray# ba i of
186+                0## -> check (i -# 1#)
187+                w   -> wordLog2# w +# (uncheckedIShiftL# i WSHIFT#)
188+
189+-- Assumption: Integer is strictly positive
190+-- First component is log2 n, second is 0# iff n is a power of two
191+integerLog2IsPowerOf2# :: Integer -> (# Int#, Int# #)
192+-- The power of 2 test is n&(n-1) == 0, thus powers of 2
193+-- are indicated bythe second component being zero.
194+integerLog2IsPowerOf2# (S# i) =
195+    case int2Word# i of
196+      w -> (# wordLog2# w, word2Int# (w `and#` (w `minusWord#` 1##)) #)
197+-- Find the log2 as above, test whether that word is a power
198+-- of 2, if so, check whether only zero bits follow.
199+integerLog2IsPowerOf2# (J# s ba) = check (s -# 1#)
200+  where
201+    check :: Int# -> (# Int#, Int# #)
202+    check i = case indexWordArray# ba i of
203+                0## -> check (i -# 1#)
204+                w   -> (# wordLog2# w +# (uncheckedIShiftL# i WSHIFT#)
205+                        , case w `and#` (w `minusWord#` 1##) of
206+                            0## -> test (i -# 1#)
207+                            _   -> 1# #)
208+    test :: Int# -> Int#
209+    test i = if i <# 0#
210+                then 0#
211+                else case indexWordArray# ba i of
212+                        0## -> test (i -# 1#)
213+                        _   -> 1#
214+
215+-- Assumption: Integer and Int# are strictly positive, Int# is less
216+-- than logBase 2 of Integer, otherwise havoc ensues.
217+-- Used only for the numerator in fromRational when the denominator
218+-- is a power of 2.
219+-- The Int# argument is log2 n minus the number of bits in the mantissa
220+-- of the target type, i.e. the index of the first non-integral bit in
221+-- the quotient.
222+--
223+-- 0# means round down (towards zero)
224+-- 1# means we have a half-integer, round to even
225+-- 2# means round up (away from zero)
226+roundingMode# :: Integer -> Int# -> Int#
227+roundingMode# (S# i) t =
228+    case int2Word# i `and#` ((uncheckedShiftL# 2## t) `minusWord#` 1##) of
229+      k -> case uncheckedShiftL# 1## t of
230+            c -> if c `gtWord#` k
231+                    then 0#
232+                    else if c `ltWord#` k
233+                            then 2#
234+                            else 1#
235+roundingMode# (J# _ ba) t =
236+    case word2Int# (int2Word# t `and#` MMASK##) of
237+      j ->      -- index of relevant bit in word
238+        case uncheckedIShiftRA# t WSHIFT# of
239+          k ->  -- index of relevant word
240+            case indexWordArray# ba k `and#`
241+                    ((uncheckedShiftL# 2## j) `minusWord#` 1##) of
242+              r ->
243+                case uncheckedShiftL# 1## j of
244+                  c -> if c `gtWord#` r
245+                        then 0#
246+                        else if c `ltWord#` r
247+                                then 2#
248+                                else test (k -# 1#)
249+  where
250+    test i = if i <# 0#
251+                then 1#
252+                else case indexWordArray# ba i of
253+                        0## -> test (i -# 1#)
254+                        _   -> 2#
255+
256+-- wordLog2# 0## = -1#
257+{-# INLINE wordLog2# #-}
258+wordLog2# :: Word# -> Int#
259+wordLog2# w =
260+  case leadingZeros of
261+   BA lz ->
262+    let zeros u = indexInt8Array# lz (word2Int# u) in
263+#if WORD_SIZE_IN_BITS == 64
264+    case uncheckedShiftRL# w 56# of
265+     a ->
266+      if a `neWord#` 0##
267+       then 64# -# zeros a
268+       else
269+        case uncheckedShiftRL# w 48# of
270+         b ->
271+          if b `neWord#` 0##
272+           then 56# -# zeros b
273+           else
274+            case uncheckedShiftRL# w 40# of
275+             c ->
276+              if c `neWord#` 0##
277+               then 48# -# zeros c
278+               else
279+                case uncheckedShiftRL# w 32# of
280+                 d ->
281+                  if d `neWord#` 0##
282+                   then 40# -# zeros d
283+                   else
284+#endif
285+                    case uncheckedShiftRL# w 24# of
286+                     e ->
287+                      if e `neWord#` 0##
288+                       then 32# -# zeros e
289+                       else
290+                        case uncheckedShiftRL# w 16# of
291+                         f ->
292+                          if f `neWord#` 0##
293+                           then 24# -# zeros f
294+                           else
295+                            case uncheckedShiftRL# w 8# of
296+                             g ->
297+                              if g `neWord#` 0##
298+                               then 16# -# zeros g
299+                               else 8# -# zeros w
300+
301+#endif
302+
303+-- Lookup table
304+data BA = BA ByteArray#
305+
306+leadingZeros :: BA
307+leadingZeros =
308+    let mkArr s =
309+          case newByteArray# 256# s of
310+            (# s1, mba #) ->
311+              case writeInt8Array# mba 0# 9# s1 of
312+                s2 ->
313+                  let fillA lim val idx st =
314+                        if idx ==# 256#
315+                          then st
316+                          else if idx <# lim
317+                                then case writeInt8Array# mba idx val st of
318+                                        nx -> fillA lim val (idx +# 1#) nx
319+                                else fillA (2# *# lim) (val -# 1#) idx st
320+                  in case fillA 2# 8# 1# s2 of
321+                      s3 -> case unsafeFreezeByteArray# mba s3 of
322+                              (# _, ba #) -> ba
323+    in case mkArr realWorld# of
324+        b -> BA b
325hunk ./integer-gmp.cabal 26
326     build-depends: ghc-prim
327     exposed-modules: GHC.Integer
328                      GHC.Integer.GMP.Internals
329+                     GHC.Integer.Logarithms
330+                     GHC.Integer.Logarithms.Internals
331     other-modules: GHC.Integer.Type
332     extensions: CPP, MagicHash, UnboxedTuples, NoImplicitPrelude,
333                 ForeignFunctionInterface, UnliftedFFITypes
334}
335[Fix Haddock markup
336Daniel Fischer <daniel.is.fischer@googlemail.com>**20110330231710
337 Ignore-this: ad1657f7c2e512a41f9d53a77d799013
338] hunk ./GHC/Integer/Logarithms.hs 17
339 --   whose logarithm is sought, should be positive, otherwise the
340 --   result is meaningless.
341 --
342--- >
343---   base ^ integerLogBase# base m <= m < base ^ (integerLogBase# base m + 1)
344--- >
345+-- > base ^ integerLogBase# base m <= m < base ^ (integerLogBase# base m + 1)
346 --
347 -- for @base > 1@ and @m > 0@.
348 integerLogBase# :: Integer -> Integer -> Int#
349
350Context:
351
352[Call the final build system phase "final" rather than ""
353Ian Lynagh <igloo@earth.li>**20110206203232
354 Ignore-this: 929994164005f2449ee56ab8a0c07fab
355]
356[Update for changes in GHC's build system
357Ian Lynagh <igloo@earth.li>**20110122194756
358 Ignore-this: e4e98a7ff8a7800f228f59e9452746cf
359]
360[Correct the gmp build phase
361Ian Lynagh <igloo@earth.li>**20110117122245
362 Ignore-this: bc26aafe9526a942f5a381fb3688d7a9
363]
364[Tidy up gmp cleaning
365Ian Lynagh <igloo@earth.li>**20110117121224
366 Ignore-this: 25007c0d1482705f5390e29a86ed6a66
367]
368[Add extensions to LANGUAGE pragmas
369Ian Lynagh <igloo@earth.li>**20110111003050]
370[Fix unknown symbol base_ControlziExceptionziBase_patError_info by helping GHC generate smarter core.
371Edward Z. Yang <ezyang@mit.edu>**20101204013010
372 Ignore-this: df2991ab1f4321c8777af7f7c1415d29
373]
374[Add LANGUAGE BangPatterns to modules that use bang patterns
375simonpj@microsoft.com**20101112170604
376 Ignore-this: bd8280707c084644c185d5fb01e583f0
377]
378[Add a rewrite rule for toInt# so literals work right
379simonpj@microsoft.com**20101026082955
380 Ignore-this: 2e7646769926eebff6e49d84e1271089
381 
382 See the comments with toInt#, but the key point is
383 that we want (fromInteger 1)::Int to yield (I# 1)!
384]
385[Follow GHC.Bool/GHC.Types merge
386Ian Lynagh <igloo@earth.li>**20101023153631
387 Ignore-this: 4ce6102919eccb7335756bd4001a2322
388]
389[Bump version number to 0.2.0.2
390Ian Lynagh <igloo@earth.li>**20100916170032]
391[Fix compile warning on 32bit machine
392David Terei <davidterei@gmail.com>**20100817103407
393 Ignore-this: 30b715c759d3721a4651c3c94054813
394]
395[fix hashInteger to be the same as fromIntegral, and document it (#4108)
396Simon Marlow <marlowsd@gmail.com>**20100813153142
397 Ignore-this: 5778949a68115bd65464b2b3d4bf4834
398]
399[implement integer2Int# and integer2Word# in Haskell, not foreign prim
400Simon Marlow <marlowsd@gmail.com>**20100813152926
401 Ignore-this: e06beace47751538e72e7b1615ff6dcf
402]
403[Use the stage-specific CONF_CC_OPTS variables
404Ian Lynagh <igloo@earth.li>**20100723135933]
405[TAG Haskell 2010 report generated
406Simon Marlow <marlowsd@gmail.com>**20100705150919
407 Ignore-this: 9e76b0809ef3e0cd86b2dd0efb9c0fb7
408]
409Patch bundle hash:
410e5680d9c3fb3479e4478757e0dbb7c7d4393d2eb