[Profile] handle select instruction in 'expect' lowering

Builtin expect lowering currently ignores select. This patch
fixes the issue

Differential Revision: http://reviews.llvm.org/D24166

llvm-svn: 280547
This commit is contained in:
Xinliang David Li 2016-09-02 22:03:40 +00:00
parent eaeafb2b4f
commit 40afd5c9e4
2 changed files with 35 additions and 11 deletions

View File

@ -83,9 +83,8 @@ static bool handleSwitchExpect(SwitchInst &SI) {
return true; return true;
} }
static bool handleBranchExpect(BranchInst &BI) { // Handle both BranchInst and SelectInst.
if (BI.isUnconditional()) template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
return false;
// Handle non-optimized IR code like: // Handle non-optimized IR code like:
// %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
@ -98,9 +97,9 @@ static bool handleBranchExpect(BranchInst &BI) {
CallInst *CI; CallInst *CI;
ICmpInst *CmpI = dyn_cast<ICmpInst>(BI.getCondition()); ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition());
if (!CmpI) { if (!CmpI) {
CI = dyn_cast<CallInst>(BI.getCondition()); CI = dyn_cast<CallInst>(BSI.getCondition());
} else { } else {
if (CmpI->getPredicate() != CmpInst::ICMP_NE) if (CmpI->getPredicate() != CmpInst::ICMP_NE)
return false; return false;
@ -129,15 +128,22 @@ static bool handleBranchExpect(BranchInst &BI) {
else else
Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight);
BI.setMetadata(LLVMContext::MD_prof, Node); BSI.setMetadata(LLVMContext::MD_prof, Node);
if (CmpI) if (CmpI)
CmpI->setOperand(0, ArgValue); CmpI->setOperand(0, ArgValue);
else else
BI.setCondition(ArgValue); BSI.setCondition(ArgValue);
return true; return true;
} }
static bool handleBranchExpect(BranchInst &BI) {
if (BI.isUnconditional())
return false;
return handleBrSelExpect<BranchInst>(BI);
}
static bool lowerExpectIntrinsic(Function &F) { static bool lowerExpectIntrinsic(Function &F) {
bool Changed = false; bool Changed = false;
@ -151,11 +157,19 @@ static bool lowerExpectIntrinsic(Function &F) {
ExpectIntrinsicsHandled++; ExpectIntrinsicsHandled++;
} }
// Remove llvm.expect intrinsics. // Remove llvm.expect intrinsics. Iterate backwards in order
for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;) { // to process select instructions before the intrinsic gets
CallInst *CI = dyn_cast<CallInst>(BI++); // removed.
if (!CI) for (auto BI = BB.rbegin(), BE = BB.rend(); BI != BE;) {
Instruction *Inst = &*BI++;
CallInst *CI = dyn_cast<CallInst>(Inst);
if (!CI) {
if (SelectInst *SI = dyn_cast<SelectInst>(Inst)) {
if (handleBrSelExpect(*SI))
ExpectIntrinsicsHandled++;
}
continue; continue;
}
Function *Fn = CI->getCalledFunction(); Function *Fn = CI->getCalledFunction();
if (Fn && Fn->getIntrinsicID() == Intrinsic::expect) { if (Fn && Fn->getIntrinsicID() == Intrinsic::expect) {

View File

@ -273,6 +273,16 @@ return: ; preds = %if.end, %if.then
ret i32 %0 ret i32 %0
} }
; CHECK-LABEL: @test10(
define i32 @test10(i64 %t6) {
%t7 = call i64 @llvm.expect.i64(i64 %t6, i64 0)
%t8 = icmp ne i64 %t7, 0
%t9 = select i1 %t8, i32 1, i32 2
; CHECK: select{{.*}}, !prof !1
ret i32 %t9
}
declare i1 @llvm.expect.i1(i1, i1) nounwind readnone declare i1 @llvm.expect.i1(i1, i1) nounwind readnone
; CHECK: !0 = !{!"branch_weights", i32 2000, i32 1} ; CHECK: !0 = !{!"branch_weights", i32 2000, i32 1}