<div dir="ltr">Hi Jakob,<div><br></div><div>Have you seen ARM's breakage?</div><div><br></div><div><a href="http://lab.llvm.org:8011/builders/clang-native-arm-cortex-a9/builds/9175/steps/check-all/logs/LLVM-Unit%3A%3ABlockFrequency.Divide">http://lab.llvm.org:8011/builders/clang-native-arm-cortex-a9/builds/9175/steps/check-all/logs/LLVM-Unit%3A%3ABlockFrequency.Divide</a><br>
</div><div><br></div><div>cheers,</div><div>--renato</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 28 June 2013 19:23, Jakob Stoklund Olesen <span dir="ltr"><<a href="mailto:stoklund@2pi.dk" target="_blank">stoklund@2pi.dk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: stoklund<br>
Date: Fri Jun 28 13:23:42 2013<br>
New Revision: 185184<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=185184&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=185184&view=rev</a><br>
Log:<br>
Add a division operator to BlockFrequency.<br>
<br>
Allow a BlockFrequency to be divided by a non-zero BranchProbability<br>
with saturating arithmetic. This will be used to compute the frequency<br>
of a loop header given the probability of leaving the loop.<br>
<br>
Our long division algorithm already saturates on overflow, so that was a<br>
freebie.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/Support/BlockFrequency.h<br>
    llvm/trunk/lib/Support/BlockFrequency.cpp<br>
    llvm/trunk/unittests/Support/BlockFrequencyTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Support/BlockFrequency.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/BlockFrequency.h?rev=185184&r1=185183&r2=185184&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/BlockFrequency.h?rev=185184&r1=185183&r2=185184&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/Support/BlockFrequency.h (original)<br>
+++ llvm/trunk/include/llvm/Support/BlockFrequency.h Fri Jun 28 13:23:42 2013<br>
@@ -27,6 +27,9 @@ class BlockFrequency {<br>
   uint64_t Frequency;<br>
   static const int64_t ENTRY_FREQ = 1 << 14;<br>
<br>
+  // Scale frequency by N/D, saturating on overflow.<br>
+  void scale(uint32_t N, uint32_t D);<br>
+<br>
 public:<br>
   BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }<br>
<br>
@@ -42,6 +45,11 @@ public:<br>
   BlockFrequency &operator*=(const BranchProbability &Prob);<br>
   const BlockFrequency operator*(const BranchProbability &Prob) const;<br>
<br>
+  /// \brief Divide by a non-zero branch probability using saturating<br>
+  /// arithmetic.<br>
+  BlockFrequency &operator/=(const BranchProbability &Prob);<br>
+  BlockFrequency operator/(const BranchProbability &Prob) const;<br>
+<br>
   /// \brief Adds another block frequency using saturating arithmetic.<br>
   BlockFrequency &operator+=(const BlockFrequency &Freq);<br>
   const BlockFrequency operator+(const BlockFrequency &Freq) const;<br>
<br>
Modified: llvm/trunk/lib/Support/BlockFrequency.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/BlockFrequency.cpp?rev=185184&r1=185183&r2=185184&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/BlockFrequency.cpp?rev=185184&r1=185183&r2=185184&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Support/BlockFrequency.cpp (original)<br>
+++ llvm/trunk/lib/Support/BlockFrequency.cpp Fri Jun 28 13:23:42 2013<br>
@@ -42,12 +42,14 @@ void mult96bit(uint64_t freq, uint32_t N<br>
 }<br>
<br>
<br>
-/// div96bit - Divide 96-bit value stored in W array by D. Return 64-bit frequency.<br>
+/// div96bit - Divide 96-bit value stored in W array by D.<br>
+/// Return 64-bit quotient, saturated to UINT64_MAX on overflow.<br>
 uint64_t div96bit(uint64_t W[2], uint32_t D) {<br>
   uint64_t y = W[0];<br>
   uint64_t x = W[1];<br>
   int i;<br>
<br>
+  // This long division algorithm automatically saturates on overflow.<br>
   for (i = 1; i <= 64 && x; ++i) {<br>
     uint32_t t = (int)x >> 31;<br>
     x = (x << 1) | (y >> 63);<br>
@@ -63,31 +65,30 @@ uint64_t div96bit(uint64_t W[2], uint32_<br>
<br>
 }<br>
<br>
+void BlockFrequency::scale(uint32_t N, uint32_t D) {<br>
+  assert(D != 0 && "Division by zero");<br>
<br>
-BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {<br>
-  uint32_t n = Prob.getNumerator();<br>
-  uint32_t d = Prob.getDenominator();<br>
-<br>
-  assert(n <= d && "Probability must be less or equal to 1.");<br>
-<br>
-  // Calculate Frequency * n.<br>
-  uint64_t mulLo = (Frequency & UINT32_MAX) * n;<br>
-  uint64_t mulHi = (Frequency >> 32) * n;<br>
-  uint64_t mulRes = (mulHi << 32) + mulLo;<br>
-<br>
-  // If there was overflow use 96-bit operations.<br>
-  if (mulHi > UINT32_MAX || mulRes < mulLo) {<br>
-    // 96-bit value represented as W[1]:W[0].<br>
-    uint64_t W[2];<br>
-<br>
-    // Probability is less or equal to 1 which means that results must fit<br>
-    // 64-bit.<br>
-    mult96bit(Frequency, n, W);<br>
-    Frequency = div96bit(W, d);<br>
-    return *this;<br>
+  // Calculate Frequency * N.<br>
+  uint64_t MulLo = (Frequency & UINT32_MAX) * N;<br>
+  uint64_t MulHi = (Frequency >> 32) * N;<br>
+  uint64_t MulRes = (MulHi << 32) + MulLo;<br>
+<br>
+  // If the product fits in 64 bits, just use built-in division.<br>
+  if (MulHi <= UINT32_MAX && MulRes <= MulLo) {<br>
+    Frequency = MulRes / D;<br>
+    return;<br>
   }<br>
<br>
-  Frequency = mulRes / d;<br>
+  // Product overflowed, use 96-bit operations.<br>
+  // 96-bit value represented as W[1]:W[0].<br>
+  uint64_t W[2];<br>
+  mult96bit(Frequency, N, W);<br>
+  Frequency = div96bit(W, D);<br>
+  return;<br>
+}<br>
+<br>
+BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {<br>
+  scale(Prob.getNumerator(), Prob.getDenominator());<br>
   return *this;<br>
 }<br>
<br>
@@ -98,6 +99,17 @@ BlockFrequency::operator*(const BranchPr<br>
   return Freq;<br>
 }<br>
<br>
+BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) {<br>
+  scale(Prob.getDenominator(), Prob.getNumerator());<br>
+  return *this;<br>
+}<br>
+<br>
+BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const {<br>
+  BlockFrequency Freq(Frequency);<br>
+  Freq /= Prob;<br>
+  return Freq;<br>
+}<br>
+<br>
 BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {<br>
   uint64_t Before = Freq.Frequency;<br>
   Frequency += Freq.Frequency;<br>
<br>
Modified: llvm/trunk/unittests/Support/BlockFrequencyTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/BlockFrequencyTest.cpp?rev=185184&r1=185183&r2=185184&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/BlockFrequencyTest.cpp?rev=185184&r1=185183&r2=185184&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/unittests/Support/BlockFrequencyTest.cpp (original)<br>
+++ llvm/trunk/unittests/Support/BlockFrequencyTest.cpp Fri Jun 28 13:23:42 2013<br>
@@ -52,6 +52,24 @@ TEST(BlockFrequencyTest, MaxToMax) {<br>
   EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);<br>
 }<br>
<br>
+TEST(BlockFrequency, Divide) {<br>
+  BlockFrequency Freq(0x3333333333333333ULL);<br>
+  Freq /= BranchProbability(1, 2);<br>
+  EXPECT_EQ(Freq.getFrequency(), 0x6666666666666666ULL);<br>
+}<br>
+<br>
+TEST(BlockFrequencyTest, Saturate) {<br>
+  BlockFrequency Freq(0x3333333333333333ULL);<br>
+  Freq /= BranchProbability(100, 300);<br>
+  EXPECT_EQ(Freq.getFrequency(), 0x9999999999999999ULL);<br>
+  Freq /= BranchProbability(1, 2);<br>
+  EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);<br>
+<br>
+  Freq = 0x1000000000000000ULL;<br>
+  Freq /= BranchProbability(10000, 160000);<br>
+  EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);<br>
+}<br>
+<br>
 TEST(BlockFrequencyTest, ProbabilityCompare) {<br>
   BranchProbability A(4, 5);<br>
   BranchProbability B(4U << 29, 5U << 29);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>