diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-04-29 16:20:05 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-04-29 16:20:05 +0000 |
commit | d22bea7dad0a35f70a4dc21a0094fc7457533fb6 (patch) | |
tree | 6bf3d74f99eafae385aec1e0430241783b520db5 | |
parent | 4ac56cf249a5da8dd15f4c89bb8081f08e873be5 (diff) | |
download | bcm5719-llvm-d22bea7dad0a35f70a4dc21a0094fc7457533fb6.tar.gz bcm5719-llvm-d22bea7dad0a35f70a4dc21a0094fc7457533fb6.zip |
blockfreq: Defer to BranchProbability::scale()
`BlockMass` can now defer to `BranchProbability::scale()`.
llvm-svn: 207547
-rw-r--r-- | llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h | 29 | ||||
-rw-r--r-- | llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp | 26 |
2 files changed, 4 insertions, 51 deletions
diff --git a/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h index e12bfd9cb73..7f7d266f7bf 100644 --- a/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -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; } diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp index c78ed88ab65..4a61e3446db 100644 --- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp +++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp @@ -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); |