/// isFormingBranchFromSelectProfitable - Returns true if a SelectInst should be /// turned into an explicit branch. static bool isFormingBranchFromSelectProfitable(SelectInst *SI) { // FIXME: This should use the same heuristics as IfConversion to determine // whether a select is better represented as a branch. This requires that // branch probability metadata is preserved for the select, which is not the // case currently. CmpInst *Cmp = dyn_cast<CmpInst>(SI->getCondition()); // If the branch is predicted right, an out of order CPU can avoid blocking on // the compare. Emit cmovs on compares with a memory operand as branches to // avoid stalls on the load from memory. If the compare has more than one use // there's probably another cmov or setcc around so it's not worth emitting a // branch. if (!Cmp) return false; Value *CmpOp0 = Cmp->getOperand(0); Value *CmpOp1 = Cmp->getOperand(1); // We check that the memory operand has one use to avoid uses of the loaded // value directly after the compare, making branches unprofitable. return Cmp->hasOneUse() && ((isa<LoadInst>(CmpOp0) && CmpOp0->hasOneUse()) || (isa<LoadInst>(CmpOp1) && CmpOp1->hasOneUse())); }
/// Returns true if the select instruction has users in the compare-and-add /// reduction pattern below. The select instruction argument is the last one /// in the sequence. /// /// %sum.1 = phi ... /// ... /// %cmp = fcmp pred %0, %CFP /// %add = fadd %0, %sum.1 /// %sum.2 = select %cmp, %add, %sum.1 RecurrenceDescriptor::InstDesc RecurrenceDescriptor::isConditionalRdxPattern( RecurrenceKind Kind, Instruction *I) { SelectInst *SI = dyn_cast<SelectInst>(I); if (!SI) return InstDesc(false, I); CmpInst *CI = dyn_cast<CmpInst>(SI->getCondition()); // Only handle single use cases for now. if (!CI || !CI->hasOneUse()) return InstDesc(false, I); Value *TrueVal = SI->getTrueValue(); Value *FalseVal = SI->getFalseValue(); // Handle only when either of operands of select instruction is a PHI // node for now. if ((isa<PHINode>(*TrueVal) && isa<PHINode>(*FalseVal)) || (!isa<PHINode>(*TrueVal) && !isa<PHINode>(*FalseVal))) return InstDesc(false, I); Instruction *I1 = isa<PHINode>(*TrueVal) ? dyn_cast<Instruction>(FalseVal) : dyn_cast<Instruction>(TrueVal); if (!I1 || !I1->isBinaryOp()) return InstDesc(false, I); Value *Op1, *Op2; if ((m_FAdd(m_Value(Op1), m_Value(Op2)).match(I1) || m_FSub(m_Value(Op1), m_Value(Op2)).match(I1)) && I1->isFast()) return InstDesc(Kind == RK_FloatAdd, SI); if (m_FMul(m_Value(Op1), m_Value(Op2)).match(I1) && (I1->isFast())) return InstDesc(Kind == RK_FloatMult, SI); return InstDesc(false, I); }