From: Duncan P. N. Exon Smith Date: Tue, 29 Apr 2014 16:20:05 +0000 (+0000) Subject: blockfreq: Defer to BranchProbability::scale() X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6919443535aad0df04be44252d6f4a0b6added43;p=oota-llvm.git blockfreq: Defer to BranchProbability::scale() `BlockMass` can now defer to `BranchProbability::scale()`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207547 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index e12bfd9cb73..7f7d266f7bf 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/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/lib/Analysis/BlockFrequencyInfoImpl.cpp b/lib/Analysis/BlockFrequencyInfoImpl.cpp index c78ed88ab65..4a61e3446db 100644 --- a/lib/Analysis/BlockFrequencyInfoImpl.cpp +++ b/lib/Analysis/BlockFrequencyInfoImpl.cpp @@ -311,32 +311,6 @@ std::pair 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 BlockMass::toFloat() const { if (isFull()) return UnsignedFloat(1, 0);