... | ... | @@ -57,11 +57,11 @@ GMP memory is integrated with the [RunTime System's](commentary/rts) (RTS's) [St |
|
|
If you want to help with replacing GMP or do it yourself, you will have to work with the GC and RTS system. The parts you will have to modify are written in C and C--, with configuration and assembly done through the Makefiles. You should have an understanding of:
|
|
|
|
|
|
- how the GC works and how memory from GMP is integrated with it;
|
|
|
- some C--/Cmm (this is fairly basic if you know C well, though the same adage for knowing C well holds for C--: if you know Assembler well enough to understand and debug C in it you will be much better off), the only real documentation on C-- itself is in the [C-- manual (PDF)](http://cminusminus.org/extern/man2.pdf), from cminusminus.org; the implementation of C-- for GHC is performed by several Haskell modules in the directory [compiler/cmm/](/trac/ghc/browser/ghc/compiler/cmm/) of the HEAD branch, see [http://darcs.haskell.org/ghc](http://darcs.haskell.org/ghc)), and see [the new Commentary Cmm page](commentary/compiler/cmm-type); and,
|
|
|
- some C--/Cmm (this is fairly basic if you know C well, though the same adage for knowing C well holds for C--: if you know Assembler well enough to understand and debug C in it you will be much better off), the only real documentation on C-- itself is in the [C-- manual (PDF)](http://cminusminus.org/extern/man2.pdf), from cminusminus.org; the implementation of C-- for GHC is performed by several Haskell modules in the directory [compiler/cmm/](/ghc/ghc/tree/master/ghc/compiler/cmm/) of the HEAD branch, see [http://darcs.haskell.org/ghc](http://darcs.haskell.org/ghc)), and see [the new Commentary Cmm page](commentary/compiler/cmm-type); and,
|
|
|
- makefiles and configuration scripts.
|
|
|
|
|
|
|
|
|
A guide to GHC primitives is available (in an unformatted version) in [/compiler/prelude/primops.txt.pp](/trac/ghc/browser/ghc//compiler/prelude/primops.txt.pp); there is a formatted version (from the latest build) at [http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html). (See [The (new) GHC Commentary](commentary)[PrimOps](commentary/prim-ops) page for an excellent description of how primitive operations are implemented. A highly recommended introduction directly related to GMP is [AddingNewPrimitiveOperations](adding-new-primitive-operations).) In primops.txt.pp--better yet, [GHC.Prim](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html)--you might want to search for the text `"section "The word size story.""`, and especially the text `"section "Integer#""` or just go to [The word size story](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html#1) and [Integer](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html#8). The Haskell definition of the Integer data type is in [/packages/base/GHC/Num.lhs](http://darcs.haskell.org/packages/base/GHC/Num.lhs).
|
|
|
A guide to GHC primitives is available (in an unformatted version) in [/compiler/prelude/primops.txt.pp](/ghc/ghc/tree/master/ghc//compiler/prelude/primops.txt.pp); there is a formatted version (from the latest build) at [http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html). (See [The (new) GHC Commentary](commentary)[PrimOps](commentary/prim-ops) page for an excellent description of how primitive operations are implemented. A highly recommended introduction directly related to GMP is [AddingNewPrimitiveOperations](adding-new-primitive-operations).) In primops.txt.pp--better yet, [GHC.Prim](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html)--you might want to search for the text `"section "The word size story.""`, and especially the text `"section "Integer#""` or just go to [The word size story](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html#1) and [Integer](http://www.haskell.org/ghc/dist/current/docs/libraries/base/GHC-Prim.html#8). The Haskell definition of the Integer data type is in [/packages/base/GHC/Num.lhs](http://darcs.haskell.org/packages/base/GHC/Num.lhs).
|
|
|
|
|
|
|
|
|
Other basic recommended reading is:
|
... | ... | @@ -101,7 +101,7 @@ There are several problems with the current GMP implementation: |
|
|
> Most of the suggestions in this section come from discussions in the glasgow-haskell-users list thread [returning to Cost of Integer](http://www.haskell.org/pipermail/glasgow-haskell-users/2006-July/010654.html). In particular, [John Meacham's suggestion](http://www.haskell.org/pipermail/glasgow-haskell-users/2006-July/010660.html) to use a ForeignPtr to data held by the normal GMP system library and store the value in an unboxed Int if the number of significant digits in Integer could fit into the size of an Int.
|
|
|
|
|
|
>
|
|
|
> The current GMP implementation of Integer, defined in [libraries/base/GHC/Num.lhs](/trac/ghc/browser/ghc/libraries/base/GHC/Num.lhs), is:
|
|
|
> The current GMP implementation of Integer, defined in [libraries/base/GHC/Num.lhs](/ghc/ghc/tree/master/ghc/libraries/base/GHC/Num.lhs), is:
|
|
|
>
|
|
|
> ```
|
|
|
> dataInteger=S#Int#-- small integers#ifndef ILX|J#Int#ByteArray#-- large integers#else|J#Void BigInteger-- .NET big ints
|
... | ... | @@ -123,25 +123,25 @@ There are several problems with the current GMP implementation: |
|
|
|
|
|
Note: references are relative to the main directory of the source distribution; links below are to the darcs repository at [http://darcs.haskell.org/ghc](http://darcs.haskell.org/ghc), created with the `[[GhcFile(path/to/file)]]` script (see [Commentary](commentary)).
|
|
|
|
|
|
- [configure.ac](/trac/ghc/browser/ghc/configure.ac) (*Modify*: remove GMP related material; replace with MP library requirements)
|
|
|
- [configure.ac](/ghc/ghc/tree/master/ghc/configure.ac) (*Modify*: remove GMP related material; replace with MP library requirements)
|
|
|
|
|
|
- [compiler/prelude/primops.txt.pp](/trac/ghc/browser/ghc/compiler/prelude/primops.txt.pp) (*Modify*: Integer material)
|
|
|
- [compiler/prelude/PrelNames.lhs](/trac/ghc/browser/ghc/compiler/prelude/PrelNames.lhs) (*Reference*: integerTyConName and similar)
|
|
|
- [compiler/prelude/primops.txt.pp](/ghc/ghc/tree/master/ghc/compiler/prelude/primops.txt.pp) (*Modify*: Integer material)
|
|
|
- [compiler/prelude/PrelNames.lhs](/ghc/ghc/tree/master/ghc/compiler/prelude/PrelNames.lhs) (*Reference*: integerTyConName and similar)
|
|
|
- \[\[GhcFile(compiler/prelude/TysPrim.lhs)\] (*Reference*)
|
|
|
|
|
|
- [includes/Cmm.h](/trac/ghc/browser/ghc/includes/Cmm.h) (*Modify*: cpp test for `#if SIZEOF_mp_limb_t != SIZEOF_VOID_P `)
|
|
|
- [includes/MachRegs.h](/trac/ghc/browser/ghc/includes/MachRegs.h) (*Reference*: general; unrelated to GMP: may be starting point for vectorized Cmm (currently only -fvia-c allows auto-vectorization))
|
|
|
- [includes/mkDerivedConstants.c](/trac/ghc/browser/ghc/includes/mkDerivedConstants.c) (*Modify*: references to GMP `__mpz_struct`: `struct_size(MP_INT)`, `struct_field(MP_INT,_mp_alloc)`, `struct_field(MP_INT,_mp_size)`, `struct_field(MP_INT,_mp_d)` and `ctype(mp_limb_t)`. Note: mp_limb_t generally == unsigned long)
|
|
|
- [includes/Regs.h](/trac/ghc/browser/ghc/includes/Regs.h) (*Modify*: references to MP_INT, `#include "gmp.h"`; Reference: Stg registers, etc.)
|
|
|
- [includes/Rts.h](/trac/ghc/browser/ghc/includes/Rts.h) (*Modify*: reference to `#include "gmp.h"`, `extern` declarations to `__decodeDouble` and `__decodeFloat`; References to various Stg types and macros)
|
|
|
- [includes/StgMiscClosures.h](/trac/ghc/browser/ghc/includes/StgMiscClosures.h) (*Modify*: references to `RTS_FUN(...Integer)` PrimOps; *Reference*: Weak Pointers, other Stg closures)
|
|
|
- [includes/Cmm.h](/ghc/ghc/tree/master/ghc/includes/Cmm.h) (*Modify*: cpp test for `#if SIZEOF_mp_limb_t != SIZEOF_VOID_P `)
|
|
|
- [includes/MachRegs.h](/ghc/ghc/tree/master/ghc/includes/MachRegs.h) (*Reference*: general; unrelated to GMP: may be starting point for vectorized Cmm (currently only -fvia-c allows auto-vectorization))
|
|
|
- [includes/mkDerivedConstants.c](/ghc/ghc/tree/master/ghc/includes/mkDerivedConstants.c) (*Modify*: references to GMP `__mpz_struct`: `struct_size(MP_INT)`, `struct_field(MP_INT,_mp_alloc)`, `struct_field(MP_INT,_mp_size)`, `struct_field(MP_INT,_mp_d)` and `ctype(mp_limb_t)`. Note: mp_limb_t generally == unsigned long)
|
|
|
- [includes/Regs.h](/ghc/ghc/tree/master/ghc/includes/Regs.h) (*Modify*: references to MP_INT, `#include "gmp.h"`; Reference: Stg registers, etc.)
|
|
|
- [includes/Rts.h](/ghc/ghc/tree/master/ghc/includes/Rts.h) (*Modify*: reference to `#include "gmp.h"`, `extern` declarations to `__decodeDouble` and `__decodeFloat`; References to various Stg types and macros)
|
|
|
- [includes/StgMiscClosures.h](/ghc/ghc/tree/master/ghc/includes/StgMiscClosures.h) (*Modify*: references to `RTS_FUN(...Integer)` PrimOps; *Reference*: Weak Pointers, other Stg closures)
|
|
|
|
|
|
- [rts/Linker.c](/trac/ghc/browser/ghc/rts/Linker.c) (*Modify*: `SymX(__gmpn...)` and related GMP functions)
|
|
|
- [rts/Makefile](/trac/ghc/browser/ghc/rts/Makefile) (*Modify*: building GMP library)
|
|
|
- [rts/PrimOps.cmm](/trac/ghc/browser/ghc/rts/PrimOps.cmm) (*Modify*: remove GMP references; NOTE: optimisation of `/* ToDo: this is shockingly inefficient */`, see discussion below)
|
|
|
- [rts/StgPrimFloat.c](/trac/ghc/browser/ghc/rts/StgPrimFloat.c) (*Modify*: `__encodeDouble`, `__encodeFloat` and `decode` versions defined here refer to GMP; might optimise with bitwise conversion instead of union; conversion depends on whether replacement MP library uses floating point, etc.)
|
|
|
- [rts/sm/Storage.c](/trac/ghc/browser/ghc/rts/sm/Storage.c) (*Modify*: `stgAllocForGMP`, `stgReallocForGMP` and `stgDeallocForGMP`; `mp_set_memory_functions(...)`; functions on lines 811, 833, 835, 848; may use as reference for implementation if replacement MP library uses GHC-garbage collected memory)
|
|
|
- [rts/gmp/](/trac/ghc/browser/ghc/rts/gmp/) (directory) (*Modify*: recommended to remove entirely, i.e., do not add conditional compilation for users who want to keep on using GMP)
|
|
|
- [rts/Linker.c](/ghc/ghc/tree/master/ghc/rts/Linker.c) (*Modify*: `SymX(__gmpn...)` and related GMP functions)
|
|
|
- [rts/Makefile](/ghc/ghc/tree/master/ghc/rts/Makefile) (*Modify*: building GMP library)
|
|
|
- [rts/PrimOps.cmm](/ghc/ghc/tree/master/ghc/rts/PrimOps.cmm) (*Modify*: remove GMP references; NOTE: optimisation of `/* ToDo: this is shockingly inefficient */`, see discussion below)
|
|
|
- [rts/StgPrimFloat.c](/ghc/ghc/tree/master/ghc/rts/StgPrimFloat.c) (*Modify*: `__encodeDouble`, `__encodeFloat` and `decode` versions defined here refer to GMP; might optimise with bitwise conversion instead of union; conversion depends on whether replacement MP library uses floating point, etc.)
|
|
|
- [rts/sm/Storage.c](/ghc/ghc/tree/master/ghc/rts/sm/Storage.c) (*Modify*: `stgAllocForGMP`, `stgReallocForGMP` and `stgDeallocForGMP`; `mp_set_memory_functions(...)`; functions on lines 811, 833, 835, 848; may use as reference for implementation if replacement MP library uses GHC-garbage collected memory)
|
|
|
- [rts/gmp/](/ghc/ghc/tree/master/ghc/rts/gmp/) (directory) (*Modify*: recommended to remove entirely, i.e., do not add conditional compilation for users who want to keep on using GMP)
|
|
|
|
|
|
### Optimisation Opportunities
|
|
|
|
... | ... | @@ -231,7 +231,7 @@ results from initialising each struct (`mp_tmp2`, etc.) on each call, in order t |
|
|
> (b) use ForeignPtr (in Cmm, Weak Pointers--difficult to implement) to foreign threads holding the the struct/array
|
|
|
|
|
|
|
|
|
(2) Primitive Operations in [compiler/codeGen/CgPrimOp.hs](/trac/ghc/browser/ghc/compiler/codeGen/CgPrimOp.hs)
|
|
|
(2) Primitive Operations in [compiler/codeGen/CgPrimOp.hs](/ghc/ghc/tree/master/ghc/compiler/codeGen/CgPrimOp.hs)
|
|
|
|
|
|
|
|
|
Related to replacing GMP, some operations in CgPrimOP.hs such as IntAddCOp may benefit from operations defined in a replacement MP library (or, more generally, simple optimisation). For example:
|
... | ... | |