[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