aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support/BlockFrequency.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/BlockFrequency.cpp')
-rw-r--r--contrib/llvm/lib/Support/BlockFrequency.cpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Support/BlockFrequency.cpp b/contrib/llvm/lib/Support/BlockFrequency.cpp
new file mode 100644
index 000000000000..00efe90a2607
--- /dev/null
+++ b/contrib/llvm/lib/Support/BlockFrequency.cpp
@@ -0,0 +1,172 @@
+//====--------------- lib/Support/BlockFrequency.cpp -----------*- C++ -*-====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Block Frequency class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/BlockFrequency.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace llvm;
+
+/// Multiply FREQ by N and store result in W array.
+static void mult96bit(uint64_t freq, uint32_t N, uint32_t W[3]) {
+ uint64_t u0 = freq & UINT32_MAX;
+ uint64_t u1 = freq >> 32;
+
+ // Represent 96-bit value as W[2]:W[1]:W[0];
+ uint64_t t = u0 * N;
+ uint64_t k = t >> 32;
+ W[0] = t;
+ t = u1 * N + k;
+ W[1] = t;
+ W[2] = t >> 32;
+}
+
+/// Divide 96-bit value stored in W[2]:W[1]:W[0] by D. Since our word size is a
+/// 32 bit unsigned integer, we can use a short division algorithm.
+static uint64_t divrem96bit(uint32_t W[3], uint32_t D, uint32_t *Rout) {
+ // We assume that W[2] is non-zero since if W[2] is not then the user should
+ // just use hardware division.
+ assert(W[2] && "This routine assumes that W[2] is non-zero since if W[2] is "
+ "zero, the caller should just use 64/32 hardware.");
+ uint32_t Q[3] = { 0, 0, 0 };
+
+ // The generalized short division algorithm sets i to m + n - 1, where n is
+ // the number of words in the divisior and m is the number of words by which
+ // the divident exceeds the divisor (i.e. m + n == the length of the dividend
+ // in words). Due to our assumption that W[2] is non-zero, we know that the
+ // dividend is of length 3 implying since n is 1 that m = 2. Thus we set i to
+ // m + n - 1 = 2 + 1 - 1 = 2.
+ uint32_t R = 0;
+ for (int i = 2; i >= 0; --i) {
+ uint64_t PartialD = uint64_t(R) << 32 | W[i];
+ if (PartialD == 0) {
+ Q[i] = 0;
+ R = 0;
+ } else if (PartialD < D) {
+ Q[i] = 0;
+ R = uint32_t(PartialD);
+ } else if (PartialD == D) {
+ Q[i] = 1;
+ R = 0;
+ } else {
+ Q[i] = uint32_t(PartialD / D);
+ R = uint32_t(PartialD - (Q[i] * D));
+ }
+ }
+
+ // If Q[2] is non-zero, then we overflowed.
+ uint64_t Result;
+ if (Q[2]) {
+ Result = UINT64_MAX;
+ R = D;
+ } else {
+ // Form the final uint64_t result, avoiding endianness issues.
+ Result = uint64_t(Q[0]) | (uint64_t(Q[1]) << 32);
+ }
+
+ if (Rout)
+ *Rout = R;
+
+ return Result;
+}
+
+uint32_t BlockFrequency::scale(uint32_t N, uint32_t D) {
+ assert(D != 0 && "Division by zero");
+
+ // Calculate Frequency * N.
+ uint64_t MulLo = (Frequency & UINT32_MAX) * N;
+ uint64_t MulHi = (Frequency >> 32) * N;
+ uint64_t MulRes = (MulHi << 32) + MulLo;
+
+ // If the product fits in 64 bits, just use built-in division.
+ if (MulHi <= UINT32_MAX && MulRes >= MulLo) {
+ Frequency = MulRes / D;
+ return MulRes % D;
+ }
+
+ // Product overflowed, use 96-bit operations.
+ // 96-bit value represented as W[2]:W[1]:W[0].
+ uint32_t W[3];
+ uint32_t R;
+ mult96bit(Frequency, N, W);
+ Frequency = divrem96bit(W, D, &R);
+ return R;
+}
+
+BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {
+ scale(Prob.getNumerator(), Prob.getDenominator());
+ return *this;
+}
+
+const BlockFrequency
+BlockFrequency::operator*(const BranchProbability &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq *= Prob;
+ return Freq;
+}
+
+BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) {
+ scale(Prob.getDenominator(), Prob.getNumerator());
+ return *this;
+}
+
+BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq /= Prob;
+ return Freq;
+}
+
+BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
+ uint64_t Before = Freq.Frequency;
+ Frequency += Freq.Frequency;
+
+ // If overflow, set frequency to the maximum value.
+ if (Frequency < Before)
+ Frequency = UINT64_MAX;
+
+ return *this;
+}
+
+const BlockFrequency
+BlockFrequency::operator+(const BlockFrequency &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq += Prob;
+ return Freq;
+}
+
+uint32_t BlockFrequency::scale(const BranchProbability &Prob) {
+ return scale(Prob.getNumerator(), Prob.getDenominator());
+}
+
+void BlockFrequency::print(raw_ostream &OS) const {
+ // Convert fixed-point number to decimal.
+ OS << Frequency / getEntryFrequency() << ".";
+ uint64_t Rem = Frequency % getEntryFrequency();
+ uint64_t Eps = 1;
+ do {
+ Rem *= 10;
+ Eps *= 10;
+ OS << Rem / getEntryFrequency();
+ Rem = Rem % getEntryFrequency();
+ } while (Rem >= Eps/2);
+}
+
+namespace llvm {
+
+raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) {
+ Freq.print(OS);
+ return OS;
+}
+
+}