blockfreq: Defer to BranchProbability::scale()
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 29 Apr 2014 16:20:05 +0000 (16:20 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 29 Apr 2014 16:20:05 +0000 (16:20 +0000)
`BlockMass` can now defer to `BranchProbability::scale()`.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207547 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/BlockFrequencyInfoImpl.h
lib/Analysis/BlockFrequencyInfoImpl.cpp

index e12bfd9cb738eca09acace0c41743994d7235a5d..7f7d266f7bfe130116611031dc43f57e9081a30a 100644 (file)
@@ -758,31 +758,10 @@ public:
     return *this;
   }
 
-  /// \brief Multiply by a branch probability.
-  ///
-  /// Multiply by P.  Guarantees full precision.
-  ///
-  /// This could be naively implemented by multiplying by the numerator and
-  /// dividing by the denominator, but in what order?  Multiplying first can
-  /// overflow, while dividing first will lose precision (potentially, changing
-  /// a non-zero mass to zero).
-  ///
-  /// The implementation mixes the two methods.  Since \a BranchProbability
-  /// uses 32-bits and \a BlockMass 64-bits, shift the mass as far to the left
-  /// as there is room, then divide by the denominator to get a quotient.
-  /// Multiplying by the numerator and right shifting gives a first
-  /// approximation.
-  ///
-  /// Calculate the error in this first approximation by calculating the
-  /// opposite mass (multiply by the opposite numerator and shift) and
-  /// subtracting both from teh original mass.
-  ///
-  /// Add to the first approximation the correct fraction of this error value.
-  /// This time, multiply first and then divide, since there is no danger of
-  /// overflow.
-  ///
-  /// \pre P represents a fraction between 0.0 and 1.0.
-  BlockMass &operator*=(const BranchProbability &P);
+  BlockMass &operator*=(const BranchProbability &P) {
+    Mass = P.scale(Mass);
+    return *this;
+  }
 
   bool operator==(const BlockMass &X) const { return Mass == X.Mass; }
   bool operator!=(const BlockMass &X) const { return Mass != X.Mass; }
index c78ed88ab6543343eb2ad440964e3f6664b00bca..4a61e3446db8d5c650f96e37949e58fe5f286733 100644 (file)
@@ -311,32 +311,6 @@ std::pair<uint64_t, int16_t> UnsignedFloatBase::multiply64(uint64_t L,
 // BlockMass implementation.
 //
 //===----------------------------------------------------------------------===//
-BlockMass &BlockMass::operator*=(const BranchProbability &P) {
-  uint32_t N = P.getNumerator(), D = P.getDenominator();
-  assert(D && "divide by 0");
-  assert(N <= D && "fraction greater than 1");
-
-  // Fast path for multiplying by 1.0.
-  if (!Mass || N == D)
-    return *this;
-
-  // Get as much precision as we can.
-  int Shift = countLeadingZeros(Mass);
-  uint64_t ShiftedQuotient = (Mass << Shift) / D;
-  uint64_t Product = ShiftedQuotient * N >> Shift;
-
-  // Now check for what's lost.
-  uint64_t Left = ShiftedQuotient * (D - N) >> Shift;
-  uint64_t Lost = Mass - Product - Left;
-
-  // TODO: prove this assertion.
-  assert(Lost <= UINT32_MAX);
-
-  // Take the product plus a portion of the spoils.
-  Mass = Product + Lost * N / D;
-  return *this;
-}
-
 UnsignedFloat<uint64_t> BlockMass::toFloat() const {
   if (isFull())
     return UnsignedFloat<uint64_t>(1, 0);