|Version 3 (modified by 5 years ago) (diff),|
GHC Commentary: Libraries/Integer
GHC is set up to allow different implementations of the
Integer type to be chosen at build time.
Selecting an Integer implementation
You can select which implementation of Integer is used by defining
mk/build.mk. This tells the build system to build the library in
libraries/$(INTEGER_LIBRARY), and the
cIntegerLibraryType values in
Config.hs are defined accordingly.
The default value is
integer-gmp, which uses the GNU Multiple Precision Arithmetic Library (GMP) to define the Integer type and its operations.
The other implementation currently available is
integer-simple, which uses a simple (but slow, for larger Integers) pure Haskell implementation.
The Integer interface
All Integer implementations should export the same set of types and functions from
GHC.Integer. These exports are used by the
base package However, all of these types and functions must actually be defined in
GHC.Integer.Type, so that GHC knows where to find them.
How Integer is handled inside GHC
Integers are represented using the
HsInteger constructor of
HsLit for the early phases of compilation (e.g. type checking), but for later stages, once we use the
Core representation, they are converted to the
LitInteger constructor of the
Literal type by
Integers aren't "machine literals" like the other
Literal constructors, it is more convenient when writing rules to pretend that they are literals rather than having to understand their real core representation.
All of the types and functions in the
Integer interface have built-in names, e.g.
plusIntegerName, defined in compiler/prelude/PrelNames.lhs and included in
basicKnownKeyNames. This allows us to match on all of the functions in
builtinIntegerRules in compiler/prelude/PrelRules.lhs, so we can constant-fold Integer expressions.
We keep the
LitInteger representation as late as possible; in particular, it's important that this representation is used in unfoldings in interface files, so that constant folding can happen on expressions that get inlined. We only convert it to a proper core representation of Integer in compiler/coreSyn/CorePrep.lhs, where we normally use the Id for
mkInteger (which we are carrying around in the
LitInteger constructor) to build an expression like
mkInteger True [123, 456] (where the
Bool represents the sign, and the list of
Ints are 31 bit chunks of the absolute value from lowest to highest).