summaryrefslogtreecommitdiffstats
path: root/llvm/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
commit415e7656f6b26ec8fd24af6f8496f17f3bda08eb (patch)
treeaefd6cc7e69a317157266dc522f093f57bee10b6 /llvm/lib/Support/BranchProbability.cpp
parent98f3f0036ab423928a62a8ef88d43bf4b408fd47 (diff)
downloadbcm5719-llvm-415e7656f6b26ec8fd24af6f8496f17f3bda08eb.tar.gz
bcm5719-llvm-415e7656f6b26ec8fd24af6f8496f17f3bda08eb.zip
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`. llvm-svn: 207544
Diffstat (limited to 'llvm/lib/Support/BranchProbability.cpp')
-rw-r--r--llvm/lib/Support/BranchProbability.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/Support/BranchProbability.cpp b/llvm/lib/Support/BranchProbability.cpp
index e8b83e59802..c541fca3fb4 100644
--- a/llvm/lib/Support/BranchProbability.cpp
+++ b/llvm/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) {
OpenPOWER on IntegriCloud