aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/BranchProbability.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/BranchProbability.cpp')
-rw-r--r--llvm/lib/Support/BranchProbability.cpp56
1 files changed, 51 insertions, 5 deletions
diff --git a/llvm/lib/Support/BranchProbability.cpp b/llvm/lib/Support/BranchProbability.cpp
index 65878d6e3..47b06c2 100644
--- a/llvm/lib/Support/BranchProbability.cpp
+++ b/llvm/lib/Support/BranchProbability.cpp
@@ -15,17 +15,63 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
using namespace llvm;
raw_ostream &BranchProbability::print(raw_ostream &OS) const {
- return OS << N << " / " << D << " = "
- << format("%g%%", ((double)N / D) * 100.0);
+ auto GetHexDigit = [](int Val) -> char {
+ assert(Val < 16);
+ if (Val < 10)
+ return '0' + Val;
+ return 'a' + Val - 10;
+ };
+ OS << "0x";
+ for (int Digits = 0; Digits < 8; ++Digits)
+ OS << GetHexDigit(N >> (28 - Digits * 4) & 0xf);
+ OS << " / 0x";
+ for (int Digits = 0; Digits < 8; ++Digits)
+ OS << GetHexDigit(D >> (28 - Digits * 4) & 0xf);
+ OS << " = " << format("%.2f%%", ((double)N / D) * 100.0);
+ return OS;
}
void BranchProbability::dump() const { print(dbgs()) << '\n'; }
-static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
+BranchProbability::BranchProbability(uint32_t Numerator, uint32_t Denominator) {
+ assert(Denominator > 0 && "Denominator cannot be 0!");
+ assert(Numerator <= Denominator && "Probability cannot be bigger than 1!");
+ if (Denominator == D)
+ N = Numerator;
+ else {
+ uint64_t Prob64 =
+ (Numerator * static_cast<uint64_t>(D) + Denominator / 2) / Denominator;
+ N = static_cast<uint32_t>(Prob64);
+ }
+}
+
+BranchProbability &BranchProbability::operator+=(BranchProbability RHS) {
+ assert(N <= D - RHS.N &&
+ "The sum of branch probabilities should not exceed one!");
+ N += RHS.N;
+ return *this;
+}
+
+BranchProbability &BranchProbability::operator-=(BranchProbability RHS) {
+ assert(N >= RHS.N &&
+ "Can only subtract a smaller probability from a larger one!");
+ N -= RHS.N;
+ return *this;
+}
+
+// If ConstD is not zero, then replace D by ConstD so that division and modulo
+// operations by D can be optimized, in case this function is not inlined by the
+// compiler.
+template <uint32_t ConstD>
+inline uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
+ if (ConstD > 0)
+ D = ConstD;
+
assert(D && "divide by 0");
// Fast path for multiplying by 1.0.
@@ -65,9 +111,9 @@ static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
}
uint64_t BranchProbability::scale(uint64_t Num) const {
- return ::scale(Num, N, D);
+ return ::scale<D>(Num, N, D);
}
uint64_t BranchProbability::scaleByInverse(uint64_t Num) const {
- return ::scale(Num, D, N);
+ return ::scale<0>(Num, D, N);
}