Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Support/BranchProbability.cpp @ 95:afa8332a0e37
LLVM 3.8
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 13 Oct 2015 17:48:58 +0900 |
parents | 54457678186b |
children | 7d135dc70f03 |
comparison
equal
deleted
inserted
replaced
84:f3e34b893a5f | 95:afa8332a0e37 |
---|---|
13 | 13 |
14 #include "llvm/Support/BranchProbability.h" | 14 #include "llvm/Support/BranchProbability.h" |
15 #include "llvm/Support/Debug.h" | 15 #include "llvm/Support/Debug.h" |
16 #include "llvm/Support/Format.h" | 16 #include "llvm/Support/Format.h" |
17 #include "llvm/Support/raw_ostream.h" | 17 #include "llvm/Support/raw_ostream.h" |
18 #include <cassert> | |
18 | 19 |
19 using namespace llvm; | 20 using namespace llvm; |
20 | 21 |
22 const uint32_t BranchProbability::D; | |
23 | |
21 raw_ostream &BranchProbability::print(raw_ostream &OS) const { | 24 raw_ostream &BranchProbability::print(raw_ostream &OS) const { |
22 return OS << N << " / " << D << " = " | 25 // Get a percentage rounded to two decimal digits. This avoids |
23 << format("%g%%", ((double)N / D) * 100.0); | 26 // implementation-defined rounding inside printf. |
27 double Percent = rint(((double)N / D) * 100.0 * 100.0) / 100.0; | |
28 OS << format("0x%08" PRIx32 " / 0x%08" PRIx32 " = %.2f%%", N, D, Percent); | |
29 return OS; | |
24 } | 30 } |
25 | 31 |
26 void BranchProbability::dump() const { print(dbgs()) << '\n'; } | 32 void BranchProbability::dump() const { print(dbgs()) << '\n'; } |
27 | 33 |
34 BranchProbability::BranchProbability(uint32_t Numerator, uint32_t Denominator) { | |
35 assert(Denominator > 0 && "Denominator cannot be 0!"); | |
36 assert(Numerator <= Denominator && "Probability cannot be bigger than 1!"); | |
37 if (Denominator == D) | |
38 N = Numerator; | |
39 else { | |
40 uint64_t Prob64 = | |
41 (Numerator * static_cast<uint64_t>(D) + Denominator / 2) / Denominator; | |
42 N = static_cast<uint32_t>(Prob64); | |
43 } | |
44 } | |
45 | |
46 // If ConstD is not zero, then replace D by ConstD so that division and modulo | |
47 // operations by D can be optimized, in case this function is not inlined by the | |
48 // compiler. | |
49 template <uint32_t ConstD> | |
28 static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) { | 50 static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) { |
51 if (ConstD > 0) | |
52 D = ConstD; | |
53 | |
29 assert(D && "divide by 0"); | 54 assert(D && "divide by 0"); |
30 | 55 |
31 // Fast path for multiplying by 1.0. | 56 // Fast path for multiplying by 1.0. |
32 if (!Num || D == N) | 57 if (!Num || D == N) |
33 return Num; | 58 return Num; |
63 // Check for overflow. | 88 // Check for overflow. |
64 return Q < LowerQ ? UINT64_MAX : Q; | 89 return Q < LowerQ ? UINT64_MAX : Q; |
65 } | 90 } |
66 | 91 |
67 uint64_t BranchProbability::scale(uint64_t Num) const { | 92 uint64_t BranchProbability::scale(uint64_t Num) const { |
68 return ::scale(Num, N, D); | 93 return ::scale<D>(Num, N, D); |
69 } | 94 } |
70 | 95 |
71 uint64_t BranchProbability::scaleByInverse(uint64_t Num) const { | 96 uint64_t BranchProbability::scaleByInverse(uint64_t Num) const { |
72 return ::scale(Num, D, N); | 97 return ::scale<0>(Num, D, N); |
73 } | 98 } |