Skip to content

Commit

Permalink
[BranchProbability] Remove the restriction that known and unknown pro…
Browse files Browse the repository at this point in the history
…babilities cannot coexist when being normalized.

The current BranchProbability::normalizeProbabilities() forbids known and
unknown probabilities to coexist in the list. This was once used to help
capture probability exceptions but has caused some reported build
failures (https://llvm.org/bugs/show_bug.cgi?id=25838).

This patch removes this restriction by evenly distributing the complement
of the sum of all known probabilities to unknown ones. We could still
treat this as an abnormal behavior, but it is better to emit warnings in
our future profile validator.


Differential revision: http://reviews.llvm.org/D15548

llvm-svn: 255934
  • Loading branch information
Cong Hou committed Dec 17, 2015
1 parent 8e9ba04 commit 7308f42
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 11 deletions.
37 changes: 26 additions & 11 deletions llvm/include/llvm/Support/BranchProbability.h
Expand Up @@ -183,17 +183,32 @@ void BranchProbability::normalizeProbabilities(ProbabilityIter Begin,
if (Begin == End)
return;

auto UnknownProbCount =
std::count(Begin, End, BranchProbability::getUnknown());
assert((UnknownProbCount == 0 ||
UnknownProbCount == std::distance(Begin, End)) &&
"Cannot normalize probabilities with known and unknown ones.");
(void)UnknownProbCount;

uint64_t Sum = std::accumulate(
Begin, End, uint64_t(0),
[](uint64_t S, const BranchProbability &BP) { return S + BP.N; });

unsigned UnknownProbCount = 0;
uint64_t Sum = std::accumulate(Begin, End, uint64_t(0),
[&](uint64_t S, const BranchProbability &BP) {
if (!BP.isUnknown())
return S + BP.N;
UnknownProbCount++;
return S;
});

if (UnknownProbCount > 0) {
BranchProbability ProbForUnknown = BranchProbability::getZero();
// If the sum of all known probabilities is less than one, evenly distribute
// the complement of sum to unknown probabilities. Otherwise, set unknown
// probabilities to zeros and continue to normalize known probabilities.
if (Sum < BranchProbability::getDenominator())
ProbForUnknown = BranchProbability::getRaw(
(BranchProbability::getDenominator() - Sum) / UnknownProbCount);

std::replace_if(Begin, End,
[](const BranchProbability &BP) { return BP.isUnknown(); },
ProbForUnknown);

if (Sum <= BranchProbability::getDenominator())
return;
}

if (Sum == 0) {
BranchProbability BP(1, std::distance(Begin, End));
std::fill(Begin, End, BP);
Expand Down
31 changes: 31 additions & 0 deletions llvm/unittests/Support/BranchProbabilityTest.cpp
Expand Up @@ -288,6 +288,7 @@ TEST(BranchProbabilityTest, scaleBruteForce) {
}

TEST(BranchProbabilityTest, NormalizeProbabilities) {
const auto UnknownProb = BranchProbability::getUnknown();
{
SmallVector<BranchProbability, 2> Probs{{0, 1}, {0, 1}};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
Expand Down Expand Up @@ -322,6 +323,36 @@ TEST(BranchProbabilityTest, NormalizeProbabilities) {
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[2].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{0, 1}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(0, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator(), Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{1, 1}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator(), Probs[0].getNumerator());
EXPECT_EQ(0, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{1, 2}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 4> Probs{
{1, 2}, {1, 2}, {1, 2}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[1].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[2].getNumerator());
EXPECT_EQ(0, Probs[3].getNumerator());
}
}

}

0 comments on commit 7308f42

Please sign in to comment.