[MLton] IntInf implementation questions

Stephen Weeks MLton@mlton.org
Mon, 6 Feb 2006 14:12:08 -0800


> Re IntInf multiply, as I recall, the time it takes for a 32*32->64
> multiply is the same as for a 32*32->32 multiply on the x86, so if
> it could be done inline (no call to a C routine), it might still be
> faster to do the big digit multiply and then check for the right
> kind of overflow.  Probably not a big win unless you are frequently
> multiplying smalls with a product that doesn't fit.

We don't have the primitive support to do the smallMul inline, so I
guess that the right thing is to do the trick Appel mentions, which is
fast when multiplying 2 smalls to get a small.

For completeness, here is the trick.

If

 i' = 2i + 1
 j' = 2j + 1

then

 (i' - 1) * floor(j' / 2) + 1 = 2 (ij) + 1

So, one can multiply two smalls using 4 bitops: zero tag (or sub1),
shift (/2), mul, and add 1.  And as with plus, the zero tag can be
simplified at compile time if one argument is a constant.  Counting
areSmall and the overflow check, that gives 6 bitops, one test, and
one overflow check.  That should be a big win over our current
approach.

> Re dontInline, is this exported to any thing any where?

mlton -show-basis shows that it is not.  However, it is a small piece
of code and doesn't rely on any privileged primitives, so you can
easily put it in your own code.

      val dontInline: (unit -> 'a) -> 'a =
         fn f =>
         let
            val rec recur: int -> 'a =
               fn i =>
               if i = 0
                  then f ()
               else (ignore (recur (i - 1))
                     ; recur (i - 2))
         in
            recur 0
         end