mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 16:06:39 +08:00
[BranchProbability] Remove the restriction that known and unknown probabilities 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
This commit is contained in:
@@ -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;
|
||||
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;
|
||||
});
|
||||
|
||||
uint64_t Sum = std::accumulate(
|
||||
Begin, End, uint64_t(0),
|
||||
[](uint64_t S, const BranchProbability &BP) { return S + BP.N; });
|
||||
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);
|
||||
|
||||
@@ -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());
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user