bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop, PredicatedScalarEvolution &PSE, InductionDescriptor &D, bool Assume) { Type *PhiTy = Phi->getType(); // Handle integer and pointer inductions variables. // Now we handle also FP induction but not trying to make a // recurrent expression from the PHI node in-place. if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy() && !PhiTy->isFloatTy() && !PhiTy->isDoubleTy() && !PhiTy->isHalfTy()) return false; if (PhiTy->isFloatingPointTy()) return isFPInductionPHI(Phi, TheLoop, PSE.getSE(), D); const SCEV *PhiScev = PSE.getSCEV(Phi); const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); // We need this expression to be an AddRecExpr. if (Assume && !AR) AR = PSE.getAsAddRec(Phi); if (!AR) { DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); return false; } return isInductionPHI(Phi, TheLoop, PSE.getSE(), D, AR); }
bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop, PredicatedScalarEvolution &PSE, InductionDescriptor &D, bool Assume) { Type *PhiTy = Phi->getType(); // Handle integer and pointer inductions variables. // Now we handle also FP induction but not trying to make a // recurrent expression from the PHI node in-place. if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy() && !PhiTy->isFloatTy() && !PhiTy->isDoubleTy() && !PhiTy->isHalfTy()) return false; if (PhiTy->isFloatingPointTy()) return isFPInductionPHI(Phi, TheLoop, PSE.getSE(), D); const SCEV *PhiScev = PSE.getSCEV(Phi); const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); // We need this expression to be an AddRecExpr. if (Assume && !AR) AR = PSE.getAsAddRec(Phi); if (!AR) { LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); return false; } // Record any Cast instructions that participate in the induction update const auto *SymbolicPhi = dyn_cast<SCEVUnknown>(PhiScev); // If we started from an UnknownSCEV, and managed to build an addRecurrence // only after enabling Assume with PSCEV, this means we may have encountered // cast instructions that required adding a runtime check in order to // guarantee the correctness of the AddRecurrence respresentation of the // induction. if (PhiScev != AR && SymbolicPhi) { SmallVector<Instruction *, 2> Casts; if (getCastsForInductionPHI(PSE, SymbolicPhi, AR, Casts)) return isInductionPHI(Phi, TheLoop, PSE.getSE(), D, AR, &Casts); } return isInductionPHI(Phi, TheLoop, PSE.getSE(), D, AR); }
bool InductionDescriptor::isInductionPHI(PHINode *Phi, PredicatedScalarEvolution &PSE, InductionDescriptor &D, bool Assume) { Type *PhiTy = Phi->getType(); // We only handle integer and pointer inductions variables. if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy()) return false; const SCEV *PhiScev = PSE.getSCEV(Phi); const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); // We need this expression to be an AddRecExpr. if (Assume && !AR) AR = PSE.getAsAddRec(Phi); if (!AR) { DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); return false; } return isInductionPHI(Phi, PSE.getSE(), D, AR); }