summaryrefslogtreecommitdiff
path: root/lib/Support/BranchProbability.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-04-29 16:15:35 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-04-29 16:15:35 +0000
commit048f520b91e5fcabb1aa85cae3ec522ab5a539e6 (patch)
treee263b166b42d4f06416f0553649ec9eb871a4bb8 /lib/Support/BranchProbability.cpp
parentf90262a09d35f9aba24357196f961733a4291aba (diff)
downloadllvm-048f520b91e5fcabb1aa85cae3ec522ab5a539e6.tar.gz
llvm-048f520b91e5fcabb1aa85cae3ec522ab5a539e6.tar.bz2
llvm-048f520b91e5fcabb1aa85cae3ec522ab5a539e6.tar.xz
Support: Add BranchProbability::scale() and ::scaleByInverse()
Add API to `BranchProbability` for scaling big integers. Next job is to rip the logic out of `BlockMass` and `BlockFrequency`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207544 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/BranchProbability.cpp')
-rw-r--r--lib/Support/BranchProbability.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/Support/BranchProbability.cpp b/lib/Support/BranchProbability.cpp
index e8b83e5980..c541fca3fb 100644
--- a/lib/Support/BranchProbability.cpp
+++ b/lib/Support/BranchProbability.cpp
@@ -26,6 +26,53 @@ void BranchProbability::dump() const {
dbgs() << *this << '\n';
}
+static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
+ assert(D && "divide by 0");
+
+ // Fast path for multiplying by 1.0.
+ if (!Num || D == N)
+ return Num;
+
+ // Split Num into upper and lower parts to multiply, then recombine.
+ uint64_t ProductHigh = (Num >> 32) * N;
+ uint64_t ProductLow = (Num & UINT32_MAX) * N;
+
+ // Split into 32-bit digits.
+ uint32_t Upper32 = ProductHigh >> 32;
+ uint32_t Lower32 = ProductLow & UINT32_MAX;
+ uint32_t Mid32Partial = ProductHigh & UINT32_MAX;
+ uint32_t Mid32 = Mid32Partial + (ProductLow >> 32);
+
+ // Carry.
+ Upper32 += Mid32 < Mid32Partial;
+
+ // Check for overflow.
+ if (Upper32 >= D)
+ return UINT64_MAX;
+
+ uint64_t Rem = (uint64_t(Upper32) << 32) | Mid32;
+ uint64_t UpperQ = Rem / D;
+
+ // Check for overflow.
+ if (UpperQ > UINT32_MAX)
+ return UINT64_MAX;
+
+ Rem = ((Rem % D) << 32) | Lower32;
+ uint64_t LowerQ = Rem / D;
+ uint64_t Q = (UpperQ << 32) + LowerQ;
+
+ // Check for overflow.
+ return Q < LowerQ ? UINT64_MAX : Q;
+}
+
+uint64_t BranchProbability::scale(uint64_t Num) const {
+ return ::scale(Num, N, D);
+}
+
+uint64_t BranchProbability::scaleByInverse(uint64_t Num) const {
+ return ::scale(Num, D, N);
+}
+
namespace llvm {
raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) {