Hello, Using the marvelous Haskell language and the equally marvelous GHC implementation, I have over the past couple of years revived my old interest in integer factorization. The built-in support for multi-precision integer arithmetic makes Haskell a fine choice for this kind of computation. And working with numbers with several hundreds of decimal digits, I at least hope that the (undoubted) overhead of GHC Haskell when compared to, say, direct use of C is easily drowned by the time taken by the individual arithmetic operations. And Haskell is so much easier to use than C. (In addition to GHC, I use Hugs.) I have come to a point, however, where I wish to squeeze some additional drops of performance out of my programs. For that, I would like direct access to some selection of gmp functions, in addition to those that are available through the use of Integer operators. For example, to experiment with the use of Montgomery modular multiplication (Mathematics of Computation, volume 44, number 170, April 1985, pages 519-521), I would like access to the mpz_tdiv_q_2exp function that divides an integer by a power of 2 by efficient shift operations. I have considered using FFI, but although I have not given up this idea, it seems hard to do in a manner that avoids some potentially significant additional overhead. So, the idea that I am currently exploring is to add some new primitive operations to Haskell as supported by GHC. Offhand, I would not have considered it likely that going in this direction would be particularly easy. So I was happy to discover that GHC already supports certain additional direct gmp calls. For example, the GHC.Num module includes the gcdInteger function that more or less directly calls mpz_gcd, everything in a seemingly straightforward manner. Unfortunately, my attempt to mimic this has failed. In detail, this is what I have done: 1. I have expanded ghc-6.4.1-src.tar.bz2 and tried to build it (./configure + make). No errors detected and seemingly, this produced a working GHC compiler. 2. Then I changed the source as indicated in the following that compares the original with my changed version: tn@linux:~/tn/Haskell/ghc/unpack> diff -r original/ . | grep -v '^Only in \./ghc' diff -r original/ghc-6.4.1/ghc/compiler/prelude/primops.txt.pp ./ghc-6.4.1/ghc/compiler/prelude/primops.txt.pp 6a7 > -- 2006-Mar-20 20.29 / TN: Experiment with additional primitive operations 429a431,435 > primop IntegerQuot2ExpOp "quotInteger2Exp#" GenPrimOp > Int# -> ByteArr# -> Int# -> (# Int#, ByteArr# #) > {Rounds towards zero.} > with out_of_line = True > diff -r original/ghc-6.4.1/ghc/includes/StgMiscClosures.h ./ghc-6.4.1/ghc/includes/StgMiscClosures.h 10a11,12 > * 2006-Mar-21 17.05 / TN: Experiment with additional primitive operations > * 491a494 > RTS_FUN(quotInteger2Expzh_fast); diff -r original/ghc-6.4.1/ghc/rts/Linker.c ./ghc-6.4.1/ghc/rts/Linker.c 6a7,8 > * 2006-Mar-21 17.06 / TN: Experiment with additional primitive operations > * 535a538 > SymX(quotInteger2Expzh_fast) \ diff -r original/ghc-6.4.1/ghc/rts/PrimOps.cmm ./ghc-6.4.1/ghc/rts/PrimOps.cmm 6a7,8 > * 2006-03-20 23.50 / TN: Experiment with additional primitive operations > * 29a32,36 > quotInteger2Expzh_fast > { > // At this point, the call of mpz_tdiv_q_2exp will eventually be inserted > } > Only in .: original Only in .: save tn@linux:~/tn/Haskell/ghc/unpack> With these changes, make fails with the error messages rm -f GHC/PrimopWrappers.o; if [ ! -d GHC/PrimopWrappers_split ]; then mkdir GHC/PrimopWrappers_split; else /usr/bin/find GHC/PrimopWrappers_split -name '*.o' -print | xargs rm -f __rm_food; fi; ../../ghc/compiler/ghc-inplace -H16m -O -fglasgow-exts -cpp -Iinclude -"#include" HsBase.h -funbox-strict-fields -ignore-package base -O -Rghc-timing -fgenerics -fgenerics -split-objs -c GHC/PrimopWrappers.hs -o GHC/PrimopWrappers.o -ohi GHC/PrimopWrappers.hi GHC/PrimopWrappers.hs:133:29: Not in scope: `GHC.Prim.quotInteger2Exp#' <<ghc: 32263284 bytes, 4 GCs, 97412/97412 avg/max bytes residency (1 samples), 16M in use, 0.00 INIT (0.00 elapsed), 0.12 MUT (0.19 elapsed), 0.02 GC (0.04 elapsed) :ghc>> make[2]: *** [GHC/PrimopWrappers.o] Error 1 make[1]: *** [all] Error 1 make[1]: Leaving directory `/home/tn/tn/Haskell/ghc/unpack/ghc-6.4.1/libraries' make: *** [build] Error 1 So, evidently, it is not as easy to add new primitive operations as I thought. (Or, which is most likely, but embarrasingly, closer to the truth: I am not as clever as I thought I was.) In any case, if someone is able to provide some hint that enables me to proceed in this matter, I would be most grateful. For the record: tn@linux:~/tn/tmp/Haskell/work> gcc -v Using built-in specs. Target: i586-suse-linux Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,f95,java,ada --disable-checking --with-gxx-include-dir=/usr/include/c++/4.0.2 --enable-java-awt=gtk --disable-libjava-multilib --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit --without-system-libunwind --host=i586-suse-linux Thread model: posix gcc version 4.0.2 20050901 (prerelease) (SUSE Linux) tn@linux:~/tn/tmp/Haskell/work> ghc --version The Glorious Glasgow Haskell Compilation System, version 6.2 tn@linux:~/tn/tmp/Haskell/work> Best regards Thorkil Naur