From 9f2bdfb40fd1bd1f8f450db079e93ad86dad8b1d Mon Sep 17 00:00:00 2001 From: Dehao Chen Date: Tue, 14 Jun 2016 22:27:17 +0000 Subject: [PATCH] Set machine block placement hot prob threshold for both static and runtime profile. Summary: With runtime profile, we have more confidence in branch probability, thus during basic block layout, we set a lower hot prob threshold so that blocks can be layouted optimally. Reviewers: djasper, davidxl Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D20991 llvm-svn: 272729 --- llvm/lib/CodeGen/MachineBlockPlacement.cpp | 24 ++++-- .../CodeGen/MachineBranchProbabilityInfo.cpp | 6 ++ llvm/test/CodeGen/X86/block-placement.ll | 78 +++++++++++++++++++ 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp index 186daa1cb8e7..7379a3099b1b 100644 --- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp +++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp @@ -125,6 +125,7 @@ BranchFoldPlacement("branch-fold-placement", cl::init(true), cl::Hidden); extern cl::opt StaticLikelyProb; +extern cl::opt ProfileLikelyProb; namespace { class BlockChain; @@ -520,13 +521,20 @@ bool MachineBlockPlacement::shouldPredBlockBeOutlined( return false; } -// FIXME (PGO handling) -// For now this method just returns a fixed threshold. It needs to be enhanced -// such that BB and Succ is passed in so that CFG shapes are examined such that -// the threshold is computed with more precise cost model when PGO is on. -static BranchProbability getLayoutSuccessorProbThreshold() { - BranchProbability HotProb(StaticLikelyProb, 100); - return HotProb; +// When profile is not present, return the StaticLikelyProb. +// When profile is available, we need to handle the triangle-shape CFG. +static BranchProbability getLayoutSuccessorProbThreshold( + MachineBasicBlock *BB) { + if (!BB->getParent()->getFunction()->getEntryCount()) + return BranchProbability(StaticLikelyProb, 100); + if (BB->succ_size() == 2) { + const MachineBasicBlock *Succ1 = *BB->succ_begin(); + const MachineBasicBlock *Succ2 = *(BB->succ_begin() + 1); + if (Succ1->isSuccessor(Succ2) || Succ2->isSuccessor(Succ1)) + return BranchProbability( + 200 - 2 * ProfileLikelyProb, 200 - ProfileLikelyProb); + } + return BranchProbability(ProfileLikelyProb, 100); } /// Checks to see if the layout candidate block \p Succ has a better layout @@ -593,7 +601,7 @@ bool MachineBlockPlacement::hasBetterLayoutPredecessor( // edge: Prob(Succ->BB) needs to >= HotProb in order to be selected (without // profile data). - BranchProbability HotProb = getLayoutSuccessorProbThreshold(); + BranchProbability HotProb = getLayoutSuccessorProbThreshold(BB); // Forward checking. For case 2, SuccProb will be 1. if (SuccProb < HotProb) { diff --git a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp index 3554e4efa5f6..9e14cb621dd0 100644 --- a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp +++ b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp @@ -29,6 +29,12 @@ cl::opt StaticLikelyProb( cl::desc("branch probability threshold to be considered very likely"), cl::init(80), cl::Hidden); +cl::opt ProfileLikelyProb( + "profile-likely-prob", + cl::desc("branch probability threshold to be considered very likely " + "when profile is available"), + cl::init(51), cl::Hidden); + char MachineBranchProbabilityInfo::ID = 0; void MachineBranchProbabilityInfo::anchor() {} diff --git a/llvm/test/CodeGen/X86/block-placement.ll b/llvm/test/CodeGen/X86/block-placement.ll index b83180ad5095..aeea6c704176 100644 --- a/llvm/test/CodeGen/X86/block-placement.ll +++ b/llvm/test/CodeGen/X86/block-placement.ll @@ -1207,4 +1207,82 @@ exit: ret void } +define void @test_hot_branch_profile(i32* %a) !prof !6 { +; Test that a hot branch that has a probability a little larger than 60% will +; break CFG constrains when doing block placement when profile is available. +; CHECK-LABEL: test_hot_branch_profile: +; CHECK: %entry +; CHECK: %then +; CHECK: %exit +; CHECK: %else + +entry: + %gep1 = getelementptr i32, i32* %a, i32 1 + %val1 = load i32, i32* %gep1 + %cond1 = icmp ugt i32 %val1, 1 + br i1 %cond1, label %then, label %else, !prof !5 + +then: + call void @hot_function() + br label %exit + +else: + call void @cold_function() + br label %exit + +exit: + call void @hot_function() + ret void +} + +define void @test_hot_branch_triangle_profile(i32* %a) !prof !6 { +; Test that a hot branch that has a probability a little larger than 80% will +; break triangle shaped CFG constrains when doing block placement if profile +; is present. +; CHECK-LABEL: test_hot_branch_triangle_profile: +; CHECK: %entry +; CHECK: %exit +; CHECK: %then + +entry: + %gep1 = getelementptr i32, i32* %a, i32 1 + %val1 = load i32, i32* %gep1 + %cond1 = icmp ugt i32 %val1, 1 + br i1 %cond1, label %exit, label %then, !prof !5 + +then: + call void @hot_function() + br label %exit + +exit: + call void @hot_function() + ret void +} + +define void @test_hot_branch_triangle_profile_topology(i32* %a) !prof !6 { +; Test that a hot branch that has a probability between 50% and 66% will not +; break triangle shaped CFG constrains when doing block placement if profile +; is present. +; CHECK-LABEL: test_hot_branch_triangle_profile_topology: +; CHECK: %entry +; CHECK: %then +; CHECK: %exit + +entry: + %gep1 = getelementptr i32, i32* %a, i32 1 + %val1 = load i32, i32* %gep1 + %cond1 = icmp ugt i32 %val1, 1 + br i1 %cond1, label %exit, label %then, !prof !7 + +then: + call void @hot_function() + br label %exit + +exit: + call void @hot_function() + ret void +} + !5 = !{!"branch_weights", i32 84, i32 16} +!6 = !{!"function_entry_count", i32 10} +!7 = !{!"branch_weights", i32 60, i32 40}