[prev in list] [next in list] [prev in thread] [next in thread]
List: openjdk-hotspot-compiler-dev
Subject: Re: RFR: 8282365: Consolidate and improve division by constant idealizations [v47]
From: Kim Barrett <kbarrett () openjdk ! org>
Date: 2024-01-31 19:20:17
Message-ID: v8cl1oPhCegBt2GcpaMcm6CsqiSFjBlF7QJ9B5oy34c=.f074820e-99f6-40d2-ad18-976f98d169ad () github ! com
[Download RAW message or body]
On Wed, 31 Jan 2024 17:32:42 GMT, Quan Anh Mai <qamai@openjdk.org> wrote:
> > This patch implements idealisation for unsigned divisions to change a division by \
> > a constant into a series of multiplication and shift. I also change the \
> > idealisation of `DivI` to get a more efficient series when the magic constant \
> > overflows an int32.
> > In general, the idea behind a signed division transformation is that for a \
> > positive constant `d`, we would need to find constants `c` and `m` so that:
> > floor(x / d) = floor(x * c / 2**m) for 0 < x < 2**(N - 1) (1)
> > ceil(x / d) = floor(x * c / 2**m) + 1 for -2**(N - 1) <= x < 0 (2)
> >
> > The implementation in the original book takes into consideration that the machine \
> > may not be able to perform the full multiplication `x * c`, so the constant \
> > overflow and we need to add back the dividend as in `DivLNode::Ideal` cases. \
> > However, for int32 division, `x * c` cannot overflow an int64. As a result, it is \
> > always feasible to just calculate the product and shift the result.
> > For unsigned multiplication, the situation is somewhat trickier because the \
> > condition needs to be twice as strong (the condition (1) and (2) above are mostly \
> > the same). This results in the magic constant `c` calculated based on the method \
> > presented in Hacker's Delight by Henry S. Warren, Jr. may overflow an uintN. For \
> > int division, we can depend on the theorem devised by Arch D. Robison in N-Bit \
> > Unsigned Division Via N-Bit Multiply-Add, which states that there exists either:
> > c1 in uint32 and m1, such that floor(x / d) = floor(x * c1 / 2**m1) for 0 < x < \
> > 2**32 (3) c2 in uint32 and m2, such that floor(x / d) = floor((x + 1) * c2 / \
> > 2**m2) for 0 < x < 2**32 (4)
> > which means that either `x * c1` never overflows an uint64 or `(x + 1) * c2` \
> > never overflows an uint64. And we can perform a full multiplication.
> > For longs, there is no way to do a full multiplication so we do some basic \
> > transformations to achieve a computable formula. The details I have written as \
> > comments in the overflow case.
> > More tests are added to cover the possible patterns.
> >
> > Please take a look and have some reviews. Thank you very much.
>
> Quan Anh Mai has updated the pull request incrementally with one additional commit \
> since the last revision:
> further clarify variable meanings
As mentioned previously, I'm not reviewing the core magic number stuff, just the
surrounding structure. That all looks okay to me now.
-------------
Marked as reviewed by kbarrett (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/9947#pullrequestreview-1854641163
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic