summaryrefslogtreecommitdiff
path: root/include/llvm/Analysis/BlockFrequencyInfoImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Analysis/BlockFrequencyInfoImpl.h')
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h483
1 files changed, 0 insertions, 483 deletions
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index 519d01342d..73408016e0 100644
--- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -33,489 +33,6 @@
//===----------------------------------------------------------------------===//
//
-// ScaledNumber definition.
-//
-// TODO: Move to include/llvm/Support/ScaledNumber.h
-//
-//===----------------------------------------------------------------------===//
-namespace llvm {
-
-class ScaledNumberBase {
-public:
- static const int DefaultPrecision = 10;
-
- static void dump(uint64_t D, int16_t E, int Width);
- static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
- unsigned Precision);
- static std::string toString(uint64_t D, int16_t E, int Width,
- unsigned Precision);
- static int countLeadingZeros32(uint32_t N) { return countLeadingZeros(N); }
- static int countLeadingZeros64(uint64_t N) { return countLeadingZeros(N); }
- static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
-
- static std::pair<uint64_t, bool> splitSigned(int64_t N) {
- if (N >= 0)
- return std::make_pair(N, false);
- uint64_t Unsigned = N == INT64_MIN ? UINT64_C(1) << 63 : uint64_t(-N);
- return std::make_pair(Unsigned, true);
- }
- static int64_t joinSigned(uint64_t U, bool IsNeg) {
- if (U > uint64_t(INT64_MAX))
- return IsNeg ? INT64_MIN : INT64_MAX;
- return IsNeg ? -int64_t(U) : int64_t(U);
- }
-};
-
-/// \brief Simple representation of a scaled number.
-///
-/// ScaledNumber is a number represented by digits and a scale. It uses simple
-/// saturation arithmetic and every operation is well-defined for every value.
-/// It's somewhat similar in behaviour to a soft-float, but is *not* a
-/// replacement for one. If you're doing numerics, look at \a APFloat instead.
-/// Nevertheless, we've found these semantics useful for modelling certain cost
-/// metrics.
-///
-/// The number is split into a signed scale and unsigned digits. The number
-/// represented is \c getDigits()*2^getScale(). In this way, the digits are
-/// much like the mantissa in the x87 long double, but there is no canonical
-/// form so the same number can be represented by many bit representations.
-///
-/// ScaledNumber is templated on the underlying integer type for digits, which
-/// is expected to be unsigned.
-///
-/// Unlike APFloat, ScaledNumber does not model architecture floating point
-/// behaviour -- while this might make it a little faster and easier to reason
-/// about, it certainly makes it more dangerous for general numerics.
-///
-/// ScaledNumber is totally ordered. However, there is no canonical form, so
-/// there are multiple representations of most scalars. E.g.:
-///
-/// ScaledNumber(8u, 0) == ScaledNumber(4u, 1)
-/// ScaledNumber(4u, 1) == ScaledNumber(2u, 2)
-/// ScaledNumber(2u, 2) == ScaledNumber(1u, 3)
-///
-/// ScaledNumber implements most arithmetic operations. Precision is kept
-/// where possible. Uses simple saturation arithmetic, so that operations
-/// saturate to 0.0 or getLargest() rather than under or overflowing. It has
-/// some extra arithmetic for unit inversion. 0.0/0.0 is defined to be 0.0.
-/// Any other division by 0.0 is defined to be getLargest().
-///
-/// As a convenience for modifying the exponent, left and right shifting are
-/// both implemented, and both interpret negative shifts as positive shifts in
-/// the opposite direction.
-///
-/// Scales are limited to the range accepted by x87 long double. This makes
-/// it trivial to add functionality to convert to APFloat (this is already
-/// relied on for the implementation of printing).
-///
-/// Possible (and conflicting) future directions:
-///
-/// 1. Turn this into a wrapper around \a APFloat.
-/// 2. Share the algorithm implementations with \a APFloat.
-/// 3. Allow \a ScaledNumber to represent a signed number.
-template <class DigitsT> class ScaledNumber : ScaledNumberBase {
-public:
- static_assert(!std::numeric_limits<DigitsT>::is_signed,
- "only unsigned floats supported");
-
- typedef DigitsT DigitsType;
-
-private:
- typedef std::numeric_limits<DigitsType> DigitsLimits;
-
- static const int Width = sizeof(DigitsType) * 8;
- static_assert(Width <= 64, "invalid integer width for digits");
-
-private:
- DigitsType Digits;
- int16_t Scale;
-
-public:
- ScaledNumber() : Digits(0), Scale(0) {}
-
- ScaledNumber(DigitsType Digits, int16_t Scale)
- : Digits(Digits), Scale(Scale) {}
-
-private:
- ScaledNumber(const std::pair<uint64_t, int16_t> &X)
- : Digits(X.first), Scale(X.second) {}
-
-public:
- static ScaledNumber getZero() { return ScaledNumber(0, 0); }
- static ScaledNumber getOne() { return ScaledNumber(1, 0); }
- static ScaledNumber getLargest() {
- return ScaledNumber(DigitsLimits::max(), ScaledNumbers::MaxScale);
- }
- static ScaledNumber get(uint64_t N) { return adjustToWidth(N, 0); }
- static ScaledNumber getInverse(uint64_t N) {
- return get(N).invert();
- }
- static ScaledNumber getFraction(DigitsType N, DigitsType D) {
- return getQuotient(N, D);
- }
-
- int16_t getScale() const { return Scale; }
- DigitsType getDigits() const { return Digits; }
-
- /// \brief Convert to the given integer type.
- ///
- /// Convert to \c IntT using simple saturating arithmetic, truncating if
- /// necessary.
- template <class IntT> IntT toInt() const;
-
- bool isZero() const { return !Digits; }
- bool isLargest() const { return *this == getLargest(); }
- bool isOne() const {
- if (Scale > 0 || Scale <= -Width)
- return false;
- return Digits == DigitsType(1) << -Scale;
- }
-
- /// \brief The log base 2, rounded.
- ///
- /// Get the lg of the scalar. lg 0 is defined to be INT32_MIN.
- int32_t lg() const { return ScaledNumbers::getLg(Digits, Scale); }
-
- /// \brief The log base 2, rounded towards INT32_MIN.
- ///
- /// Get the lg floor. lg 0 is defined to be INT32_MIN.
- int32_t lgFloor() const { return ScaledNumbers::getLgFloor(Digits, Scale); }
-
- /// \brief The log base 2, rounded towards INT32_MAX.
- ///
- /// Get the lg ceiling. lg 0 is defined to be INT32_MIN.
- int32_t lgCeiling() const {
- return ScaledNumbers::getLgCeiling(Digits, Scale);
- }
-
- bool operator==(const ScaledNumber &X) const { return compare(X) == 0; }
- bool operator<(const ScaledNumber &X) const { return compare(X) < 0; }
- bool operator!=(const ScaledNumber &X) const { return compare(X) != 0; }
- bool operator>(const ScaledNumber &X) const { return compare(X) > 0; }
- bool operator<=(const ScaledNumber &X) const { return compare(X) <= 0; }
- bool operator>=(const ScaledNumber &X) const { return compare(X) >= 0; }
-
- bool operator!() const { return isZero(); }
-
- /// \brief Convert to a decimal representation in a string.
- ///
- /// Convert to a string. Uses scientific notation for very large/small
- /// numbers. Scientific notation is used roughly for numbers outside of the
- /// range 2^-64 through 2^64.
- ///
- /// \c Precision indicates the number of decimal digits of precision to use;
- /// 0 requests the maximum available.
- ///
- /// As a special case to make debugging easier, if the number is small enough
- /// to convert without scientific notation and has more than \c Precision
- /// digits before the decimal place, it's printed accurately to the first
- /// digit past zero. E.g., assuming 10 digits of precision:
- ///
- /// 98765432198.7654... => 98765432198.8
- /// 8765432198.7654... => 8765432198.8
- /// 765432198.7654... => 765432198.8
- /// 65432198.7654... => 65432198.77
- /// 5432198.7654... => 5432198.765
- std::string toString(unsigned Precision = DefaultPrecision) {
- return ScaledNumberBase::toString(Digits, Scale, Width, Precision);
- }
-
- /// \brief Print a decimal representation.
- ///
- /// Print a string. See toString for documentation.
- raw_ostream &print(raw_ostream &OS,
- unsigned Precision = DefaultPrecision) const {
- return ScaledNumberBase::print(OS, Digits, Scale, Width, Precision);
- }
- void dump() const { return ScaledNumberBase::dump(Digits, Scale, Width); }
-
- ScaledNumber &operator+=(const ScaledNumber &X) {
- std::tie(Digits, Scale) =
- ScaledNumbers::getSum(Digits, Scale, X.Digits, X.Scale);
- // Check for exponent past MaxScale.
- if (Scale > ScaledNumbers::MaxScale)
- *this = getLargest();
- return *this;
- }
- ScaledNumber &operator-=(const ScaledNumber &X) {
- std::tie(Digits, Scale) =
- ScaledNumbers::getDifference(Digits, Scale, X.Digits, X.Scale);
- return *this;
- }
- ScaledNumber &operator*=(const ScaledNumber &X);
- ScaledNumber &operator/=(const ScaledNumber &X);
- ScaledNumber &operator<<=(int16_t Shift) {
- shiftLeft(Shift);
- return *this;
- }
- ScaledNumber &operator>>=(int16_t Shift) {
- shiftRight(Shift);
- return *this;
- }
-
-private:
- void shiftLeft(int32_t Shift);
- void shiftRight(int32_t Shift);
-
- /// \brief Adjust two floats to have matching exponents.
- ///
- /// Adjust \c this and \c X to have matching exponents. Returns the new \c X
- /// by value. Does nothing if \a isZero() for either.
- ///
- /// The value that compares smaller will lose precision, and possibly become
- /// \a isZero().
- ScaledNumber matchScales(ScaledNumber X) {
- ScaledNumbers::matchScales(Digits, Scale, X.Digits, X.Scale);
- return X;
- }
-
-public:
- /// \brief Scale a large number accurately.
- ///
- /// Scale N (multiply it by this). Uses full precision multiplication, even
- /// if Width is smaller than 64, so information is not lost.
- uint64_t scale(uint64_t N) const;
- uint64_t scaleByInverse(uint64_t N) const {
- // TODO: implement directly, rather than relying on inverse. Inverse is
- // expensive.
- return inverse().scale(N);
- }
- int64_t scale(int64_t N) const {
- std::pair<uint64_t, bool> Unsigned = splitSigned(N);
- return joinSigned(scale(Unsigned.first), Unsigned.second);
- }
- int64_t scaleByInverse(int64_t N) const {
- std::pair<uint64_t, bool> Unsigned = splitSigned(N);
- return joinSigned(scaleByInverse(Unsigned.first), Unsigned.second);
- }
-
- int compare(const ScaledNumber &X) const {
- return ScaledNumbers::compare(Digits, Scale, X.Digits, X.Scale);
- }
- int compareTo(uint64_t N) const {
- ScaledNumber Scaled = get(N);
- int Compare = compare(Scaled);
- if (Width == 64 || Compare != 0)
- return Compare;
-
- // Check for precision loss. We know *this == RoundTrip.
- uint64_t RoundTrip = Scaled.template toInt<uint64_t>();
- return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
- }
- int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
-
- ScaledNumber &invert() { return *this = ScaledNumber::get(1) / *this; }
- ScaledNumber inverse() const { return ScaledNumber(*this).invert(); }
-
-private:
- static ScaledNumber getProduct(DigitsType LHS, DigitsType RHS) {
- return ScaledNumbers::getProduct(LHS, RHS);
- }
- static ScaledNumber getQuotient(DigitsType Dividend, DigitsType Divisor) {
- return ScaledNumbers::getQuotient(Dividend, Divisor);
- }
-
- static int countLeadingZerosWidth(DigitsType Digits) {
- if (Width == 64)
- return countLeadingZeros64(Digits);
- if (Width == 32)
- return countLeadingZeros32(Digits);
- return countLeadingZeros32(Digits) + Width - 32;
- }
-
- /// \brief Adjust a number to width, rounding up if necessary.
- ///
- /// Should only be called for \c Shift close to zero.
- ///
- /// \pre Shift >= MinScale && Shift + 64 <= MaxScale.
- static ScaledNumber adjustToWidth(uint64_t N, int32_t Shift) {
- assert(Shift >= ScaledNumbers::MinScale && "Shift should be close to 0");
- assert(Shift <= ScaledNumbers::MaxScale - 64 &&
- "Shift should be close to 0");
- auto Adjusted = ScaledNumbers::getAdjusted<DigitsT>(N, Shift);
- return Adjusted;
- }
-
- static ScaledNumber getRounded(ScaledNumber P, bool Round) {
- // Saturate.
- if (P.isLargest())
- return P;
-
- return ScaledNumbers::getRounded(P.Digits, P.Scale, Round);
- }
-};
-
-#define SCALED_NUMBER_BOP(op, base) \
- template <class DigitsT> \
- ScaledNumber<DigitsT> operator op(const ScaledNumber<DigitsT> &L, \
- const ScaledNumber<DigitsT> &R) { \
- return ScaledNumber<DigitsT>(L) base R; \
- }
-SCALED_NUMBER_BOP(+, += )
-SCALED_NUMBER_BOP(-, -= )
-SCALED_NUMBER_BOP(*, *= )
-SCALED_NUMBER_BOP(/, /= )
-SCALED_NUMBER_BOP(<<, <<= )
-SCALED_NUMBER_BOP(>>, >>= )
-#undef SCALED_NUMBER_BOP
-
-template <class DigitsT>
-raw_ostream &operator<<(raw_ostream &OS, const ScaledNumber<DigitsT> &X) {
- return X.print(OS, 10);
-}
-
-#define SCALED_NUMBER_COMPARE_TO_TYPE(op, T1, T2) \
- template <class DigitsT> \
- bool operator op(const ScaledNumber<DigitsT> &L, T1 R) { \
- return L.compareTo(T2(R)) op 0; \
- } \
- template <class DigitsT> \
- bool operator op(T1 L, const ScaledNumber<DigitsT> &R) { \
- return 0 op R.compareTo(T2(L)); \
- }
-#define SCALED_NUMBER_COMPARE_TO(op) \
- SCALED_NUMBER_COMPARE_TO_TYPE(op, uint64_t, uint64_t) \
- SCALED_NUMBER_COMPARE_TO_TYPE(op, uint32_t, uint64_t) \
- SCALED_NUMBER_COMPARE_TO_TYPE(op, int64_t, int64_t) \
- SCALED_NUMBER_COMPARE_TO_TYPE(op, int32_t, int64_t)
-SCALED_NUMBER_COMPARE_TO(< )
-SCALED_NUMBER_COMPARE_TO(> )
-SCALED_NUMBER_COMPARE_TO(== )
-SCALED_NUMBER_COMPARE_TO(!= )
-SCALED_NUMBER_COMPARE_TO(<= )
-SCALED_NUMBER_COMPARE_TO(>= )
-#undef SCALED_NUMBER_COMPARE_TO
-#undef SCALED_NUMBER_COMPARE_TO_TYPE
-
-template <class DigitsT>
-uint64_t ScaledNumber<DigitsT>::scale(uint64_t N) const {
- if (Width == 64 || N <= DigitsLimits::max())
- return (get(N) * *this).template toInt<uint64_t>();
-
- // Defer to the 64-bit version.
- return ScaledNumber<uint64_t>(Digits, Scale).scale(N);
-}
-
-template <class DigitsT>
-template <class IntT>
-IntT ScaledNumber<DigitsT>::toInt() const {
- typedef std::numeric_limits<IntT> Limits;
- if (*this < 1)
- return 0;
- if (*this >= Limits::max())
- return Limits::max();
-
- IntT N = Digits;
- if (Scale > 0) {
- assert(size_t(Scale) < sizeof(IntT) * 8);
- return N << Scale;
- }
- if (Scale < 0) {
- assert(size_t(-Scale) < sizeof(IntT) * 8);
- return N >> -Scale;
- }
- return N;
-}
-
-template <class DigitsT>
-ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
-operator*=(const ScaledNumber &X) {
- if (isZero())
- return *this;
- if (X.isZero())
- return *this = X;
-
- // Save the exponents.
- int32_t Scales = int32_t(Scale) + int32_t(X.Scale);
-
- // Get the raw product.
- *this = getProduct(Digits, X.Digits);
-
- // Combine with exponents.
- return *this <<= Scales;
-}
-template <class DigitsT>
-ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
-operator/=(const ScaledNumber &X) {
- if (isZero())
- return *this;
- if (X.isZero())
- return *this = getLargest();
-
- // Save the exponents.
- int32_t Scales = int32_t(Scale) - int32_t(X.Scale);
-
- // Get the raw quotient.
- *this = getQuotient(Digits, X.Digits);
-
- // Combine with exponents.
- return *this <<= Scales;
-}
-template <class DigitsT> void ScaledNumber<DigitsT>::shiftLeft(int32_t Shift) {
- if (!Shift || isZero())
- return;
- assert(Shift != INT32_MIN);
- if (Shift < 0) {
- shiftRight(-Shift);
- return;
- }
-
- // Shift as much as we can in the exponent.
- int32_t ScaleShift = std::min(Shift, ScaledNumbers::MaxScale - Scale);
- Scale += ScaleShift;
- if (ScaleShift == Shift)
- return;
-
- // Check this late, since it's rare.
- if (isLargest())
- return;
-
- // Shift the digits themselves.
- Shift -= ScaleShift;
- if (Shift > countLeadingZerosWidth(Digits)) {
- // Saturate.
- *this = getLargest();
- return;
- }
-
- Digits <<= Shift;
- return;
-}
-
-template <class DigitsT> void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
- if (!Shift || isZero())
- return;
- assert(Shift != INT32_MIN);
- if (Shift < 0) {
- shiftLeft(-Shift);
- return;
- }
-
- // Shift as much as we can in the exponent.
- int32_t ScaleShift = std::min(Shift, Scale - ScaledNumbers::MinScale);
- Scale -= ScaleShift;
- if (ScaleShift == Shift)
- return;
-
- // Shift the digits themselves.
- Shift -= ScaleShift;
- if (Shift >= Width) {
- // Saturate.
- *this = getZero();
- return;
- }
-
- Digits >>= Shift;
- return;
-}
-
-template <class T> struct isPodLike<ScaledNumber<T>> {
- static const bool value = true;
-};
-}
-
-//===----------------------------------------------------------------------===//
-//
// BlockMass definition.
//
// TODO: Make this private to BlockFrequencyInfoImpl or delete.