[BranchProbability] Manually round the floating point output.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 26 Sep 2015 10:09:36 +0000 (10:09 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 26 Sep 2015 10:09:36 +0000 (10:09 +0000)
llvm::format compiles down to snprintf which has no defined rounding for
floating point arguments, and MSVC has implemented it differently from
what the BSD libcs and glibc do. Try to emulate the glibc rounding
behavior to avoid changing tests.

While there simplify code a bit and move trivial methods inline.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248665 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/BranchProbability.h
lib/Support/BranchProbability.cpp

index dd43857fa2286653481cc01662f83de1d6542cf1..98b2a3d7d9a2460c26ad964cf239d957faf3c81f 100644 (file)
@@ -79,8 +79,20 @@ public:
   /// \return \c Num divided by \c this.
   uint64_t scaleByInverse(uint64_t Num) const;
 
-  BranchProbability &operator+=(BranchProbability RHS);
-  BranchProbability &operator-=(BranchProbability RHS);
+  BranchProbability &operator+=(BranchProbability RHS) {
+    assert(N <= D - RHS.N &&
+           "The sum of branch probabilities should not exceed one!");
+    N += RHS.N;
+    return *this;
+  }
+
+  BranchProbability &operator-=(BranchProbability RHS) {
+    assert(N >= RHS.N &&
+           "Can only subtract a smaller probability from a larger one!");
+    N -= RHS.N;
+    return *this;
+  }
+
   BranchProbability &operator*=(BranchProbability RHS) {
     N = (static_cast<uint64_t>(N) * RHS.N + D / 2) / D;
     return *this;
index 47b06c2e0ffbe4ea977db417d5c437c145857e09..3b0f6e6f06e42c48157190dac6b3887047e951f1 100644 (file)
 
 using namespace llvm;
 
+const uint32_t BranchProbability::D;
+
 raw_ostream &BranchProbability::print(raw_ostream &OS) const {
-  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);
+  // Get a percentage rounded to two decimal digits. This avoids
+  // implementation-defined rounding inside printf.
+  double Percent = rint(((double)N / D) * 100.0 * 100.0) / 100.0;
+  OS << format("0x%08" PRIx32 " / 0x%08" PRIx32 " = %.2f%%", N, D, Percent);
   return OS;
 }
 
@@ -50,25 +43,11 @@ BranchProbability::BranchProbability(uint32_t Numerator, uint32_t Denominator) {
   }
 }
 
-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) {
+static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
   if (ConstD > 0)
     D = ConstD;