mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[BPI] Incorrect probability reported in case of mulptiple edges.
Summary: By design 'BranchProbabilityInfo:: getEdgeProbability(const BasicBlock *Src, const BasicBlock *Dst) const' should return sum of probabilities over all edges from Src to Dst. Current implementation is buggy and returns 1/num_of_successors if probabilities are not explicitly set. Note current implementation of BPI printing has an issue as well and annotates each edge with sum of probabilities over all ages from one basic block to another. That's why 30% probability reported (instead of 10%) in the lit test. This is not urgent issue since only printing is affected. Note also current implementation assumes that either all or none edges have probabilities set. This is not the only place which uses such assumption. At least we should assert that in verifier. In addition we can think on a more robust API of BPI which would prevent situations. Reviewers: skatkov, yrouban, taewookoh Reviewed By: skatkov Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D79071
This commit is contained in:
parent
850ecb1d9c
commit
86a7336cb6
@ -936,8 +936,10 @@ BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
|
|||||||
const BasicBlock *Dst) const {
|
const BasicBlock *Dst) const {
|
||||||
auto Prob = BranchProbability::getZero();
|
auto Prob = BranchProbability::getZero();
|
||||||
bool FoundProb = false;
|
bool FoundProb = false;
|
||||||
|
uint32_t EdgeCount = 0;
|
||||||
for (const_succ_iterator I = succ_begin(Src), E = succ_end(Src); I != E; ++I)
|
for (const_succ_iterator I = succ_begin(Src), E = succ_end(Src); I != E; ++I)
|
||||||
if (*I == Dst) {
|
if (*I == Dst) {
|
||||||
|
++EdgeCount;
|
||||||
auto MapI = Probs.find(std::make_pair(Src, I.getSuccessorIndex()));
|
auto MapI = Probs.find(std::make_pair(Src, I.getSuccessorIndex()));
|
||||||
if (MapI != Probs.end()) {
|
if (MapI != Probs.end()) {
|
||||||
FoundProb = true;
|
FoundProb = true;
|
||||||
@ -945,7 +947,7 @@ BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t succ_num = std::distance(succ_begin(Src), succ_end(Src));
|
uint32_t succ_num = std::distance(succ_begin(Src), succ_end(Src));
|
||||||
return FoundProb ? Prob : BranchProbability(1, succ_num);
|
return FoundProb ? Prob : BranchProbability(EdgeCount, succ_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the edge probability for a given edge specified by PredBlock and an
|
/// Set the edge probability for a given edge specified by PredBlock and an
|
||||||
|
53
test/Analysis/BranchProbabilityInfo/switch.ll
Normal file
53
test/Analysis/BranchProbabilityInfo/switch.ll
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
|
||||||
|
; RUN: opt < %s -analyze -lazy-branch-prob | FileCheck %s
|
||||||
|
; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
declare void @g(i32)
|
||||||
|
|
||||||
|
; Check correctness of reported probabilities in case of multiple edges between
|
||||||
|
; basic blocks. In this case sum of probabilities over all edges should be
|
||||||
|
; returned by BranchProbabilityInfo::getEdgeProbability.
|
||||||
|
|
||||||
|
define void @test1(i32 %x) {
|
||||||
|
;CHECK: edge entry -> return probability is 0x0ccccccd / 0x80000000 = 10.00%
|
||||||
|
;CHECK: edge entry -> bb0 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb0 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb0 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb1 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb1 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb1 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb2 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb2 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge entry -> bb2 probability is 0x26666666 / 0x80000000 = 30.00%
|
||||||
|
;CHECK: edge bb0 -> return probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
|
||||||
|
;CHECK: edge bb1 -> return probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
|
||||||
|
;CHECK: edge bb2 -> return probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
|
||||||
|
|
||||||
|
entry:
|
||||||
|
switch i32 %x, label %return [
|
||||||
|
i32 0, label %bb0
|
||||||
|
i32 3, label %bb0
|
||||||
|
i32 6, label %bb0
|
||||||
|
i32 1, label %bb1
|
||||||
|
i32 4, label %bb1
|
||||||
|
i32 7, label %bb1
|
||||||
|
i32 2, label %bb2
|
||||||
|
i32 5, label %bb2
|
||||||
|
i32 8, label %bb2
|
||||||
|
]
|
||||||
|
|
||||||
|
bb0: ; preds = %entry, %entry, %entry
|
||||||
|
tail call void @g(i32 0)
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
bb1: ; preds = %entry, %entry, %entry
|
||||||
|
tail call void @g(i32 1)
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
bb2: ; preds = %entry, %entry, %entry
|
||||||
|
tail call void @g(i32 2)
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %bb2, %bb1, %bb0, %entry
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user