diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp index 79f0db1..52975ef 100644 --- a/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -83,9 +83,8 @@ static bool handleSwitchExpect(SwitchInst &SI) { return true; } -static bool handleBranchExpect(BranchInst &BI) { - if (BI.isUnconditional()) - return false; +// Handle both BranchInst and SelectInst. +template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) { // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) @@ -98,9 +97,9 @@ static bool handleBranchExpect(BranchInst &BI) { CallInst *CI; - ICmpInst *CmpI = dyn_cast<ICmpInst>(BI.getCondition()); + ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition()); if (!CmpI) { - CI = dyn_cast<CallInst>(BI.getCondition()); + CI = dyn_cast<CallInst>(BSI.getCondition()); } else { if (CmpI->getPredicate() != CmpInst::ICMP_NE) return false; @@ -129,15 +128,22 @@ static bool handleBranchExpect(BranchInst &BI) { else Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); - BI.setMetadata(LLVMContext::MD_prof, Node); + BSI.setMetadata(LLVMContext::MD_prof, Node); if (CmpI) CmpI->setOperand(0, ArgValue); else - BI.setCondition(ArgValue); + BSI.setCondition(ArgValue); return true; } +static bool handleBranchExpect(BranchInst &BI) { + if (BI.isUnconditional()) + return false; + + return handleBrSelExpect<BranchInst>(BI); +} + static bool lowerExpectIntrinsic(Function &F) { bool Changed = false; @@ -151,11 +157,19 @@ static bool lowerExpectIntrinsic(Function &F) { ExpectIntrinsicsHandled++; } - // Remove llvm.expect intrinsics. - for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;) { - CallInst *CI = dyn_cast<CallInst>(BI++); - if (!CI) + // Remove llvm.expect intrinsics. Iterate backwards in order + // to process select instructions before the intrinsic gets + // removed. + 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; + } Function *Fn = CI->getCalledFunction(); if (Fn && Fn->getIntrinsicID() == Intrinsic::expect) { |