bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) { if (BI->isUnconditional()) return false; // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) // %tobool = icmp ne i64 %expval, 0 // br i1 %tobool, label %if.then, label %if.end // // Or the following simpler case: // %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1) // br i1 %expval, label %if.then, label %if.end CallInst *CI; ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition()); if (!CmpI) { CI = dyn_cast<CallInst>(BI->getCondition()); } else { if (CmpI->getPredicate() != CmpInst::ICMP_NE) return false; CI = dyn_cast<CallInst>(CmpI->getOperand(0)); } if (!CI) return false; Function *Fn = CI->getCalledFunction(); if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) return false; Value *ArgValue = CI->getArgOperand(0); ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (!ExpectedValue) return false; MDBuilder MDB(CI->getContext()); MDNode *Node; // If expect value is equal to 1 it means that we are more likely to take // branch 0, in other case more likely is branch 1. if (ExpectedValue->isOne()) Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight); else Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); BI->setMetadata(LLVMContext::MD_prof, Node); if (CmpI) CmpI->setOperand(0, ArgValue); else BI->setCondition(ArgValue); return true; }
bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) { if (BI->isUnconditional()) return false; // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64.i64(i64 %conv1, i64 1) // %tobool = icmp ne i64 %expval, 0 // br i1 %tobool, label %if.then, label %if.end ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition()); if (!CmpI || CmpI->getPredicate() != CmpInst::ICMP_NE) return false; CallInst *CI = dyn_cast<CallInst>(CmpI->getOperand(0)); if (!CI) return false; Function *Fn = CI->getCalledFunction(); if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) return false; Value *ArgValue = CI->getArgOperand(0); ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (!ExpectedValue) return false; LLVMContext &Context = CI->getContext(); const Type *Int32Ty = Type::getInt32Ty(Context); bool Likely = ExpectedValue->isOne(); // If expect value is equal to 1 it means that we are more likely to take // branch 0, in other case more likely is branch 1. Value *Ops[] = { MDString::get(Context, "branch_weights"), ConstantInt::get(Int32Ty, Likely ? LikelyBranchWeight : UnlikelyBranchWeight), ConstantInt::get(Int32Ty, Likely ? UnlikelyBranchWeight : LikelyBranchWeight) }; MDNode *WeightsNode = MDNode::get(Context, Ops); BI->setMetadata(LLVMContext::MD_prof, WeightsNode); CmpI->setOperand(0, ArgValue); return true; }