forked from OSchip/llvm-project
[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:
parent
eaeafb2b4f
commit
40afd5c9e4
|
@ -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) {
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Reference in New Issue