[PATCH] D30527: Replacing float with new class Fraction for LSR alternative way of resolving complex solution
Evgeny Stupachenko via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 7 16:48:45 PST 2017
evstupac added inline comments.
================
Comment at: lib/Transforms/Scalar/LoopStrengthReduce.cpp:1069
+ uint64_t Denominator;
+ Fraction &Optimize() {
+ while (Numerator > UINT32_MAX / 2 || Denominator > UINT32_MAX / 2) {
----------------
qcolombet wrote:
> Could you add a comment explaining how the optimization work?
> The reduction does not look right to me, but my math class are way behind me :P
I suppose Numerator and Denominator will be in 31 bits for most cases. However if one of them exceed 31 bits, then operator+ could overflow.
To avoid this we need to optimize a fraction.
Converting N/D to (N/2)/(D/2) will potentially loose precision, but it is much faster than searching for common dividers. The precision we loose is not higher than ABS(N/D - (N/2)/(D/2)), which is not higher than max(D/2,N/2)/(D*D/2). Since we are working with probability N <= D. So it should be less than 1/D each step. That means precision loss is less than 1/(2^31), as D > 2^31. Which is acceptable.
I'll add the comment to sources.
================
Comment at: lib/Transforms/Scalar/LoopStrengthReduce.cpp:1082
+ Fraction() : Numerator(0), Denominator(1) {}
+ Fraction(unsigned N, unsigned D) : Numerator(N), Denominator(D) {}
+ Fraction operator/(const Fraction &Divider) const {
----------------
qcolombet wrote:
> Add an assert D != 0
ok.
================
Comment at: lib/Transforms/Scalar/LoopStrengthReduce.cpp:1087
+ Res.Denominator = Denominator / Divider.Denominator;
+ return Res;
+ }
----------------
qcolombet wrote:
> I am confused about the meaning of this operator.
> For divide, I would have expected something like:
> return operator*(Fraction(Divider.Denominator, Divider.Numerator));
Well, this is specific for our case: probability of not selecting (PoNS) for reg R.
PoNS at all is multiplication of PoNS for each use: PAll = P1*P2*...*PK (this is counted once). Suppose we want to get PoNS for particular register use - Use2. It will be PAll / P2. Numerator in PAll fraction has multiplier P2 Numerator. The same about Denominator. That way we don't need optimization.
Repository:
rL LLVM
https://reviews.llvm.org/D30527
More information about the llvm-commits
mailing list