82#define DEBUG_TYPE "loop-flatten"
84STATISTIC(NumFlattened,
"Number of loops flattened");
88 cl::desc(
"Limit on the cost of instructions that can be repeated due to "
94 cl::desc(
"Assume that the product of the two iteration "
95 "trip counts will never overflow"));
99 cl::desc(
"Widen the loop induction variables, if possible, so "
100 "overflow checks won't reject flattening"));
104 cl::desc(
"Version loops if flattened loop could overflow"));
116 Loop *OuterLoop =
nullptr;
117 Loop *InnerLoop =
nullptr;
119 PHINode *InnerInductionPHI =
nullptr;
120 PHINode *OuterInductionPHI =
nullptr;
124 Value *InnerTripCount =
nullptr;
125 Value *OuterTripCount =
nullptr;
142 bool Widened =
false;
145 PHINode *NarrowInnerInductionPHI =
nullptr;
146 PHINode *NarrowOuterInductionPHI =
nullptr;
150 Value *NewTripCount =
nullptr;
152 FlattenInfo(
Loop *OL,
Loop *IL) : OuterLoop(OL), InnerLoop(IL){};
154 bool isNarrowInductionPhi(PHINode *Phi) {
158 return NarrowInnerInductionPHI ==
Phi || NarrowOuterInductionPHI ==
Phi;
160 bool isInnerLoopIncrement(User *U) {
161 return InnerIncrement ==
U;
163 bool isOuterLoopIncrement(User *U) {
164 return OuterIncrement ==
U;
166 bool isInnerLoopTest(User *U) {
167 return InnerBranch->getCondition() ==
U;
170 bool checkOuterInductionPhiUsers(SmallPtrSet<Value *, 4> &ValidOuterPHIUses) {
171 for (User *U : OuterInductionPHI->users()) {
172 if (isOuterLoopIncrement(U))
175 auto IsValidOuterPHIUses = [&] (
User *
U) ->
bool {
176 LLVM_DEBUG(
dbgs() <<
"Found use of outer induction variable: ";
U->dump());
177 if (!ValidOuterPHIUses.
count(U)) {
178 LLVM_DEBUG(
dbgs() <<
"Did not match expected pattern, bailing\n");
186 for (
auto *K :
V->users()) {
187 if (!IsValidOuterPHIUses(K))
193 if (!IsValidOuterPHIUses(U))
199 bool matchLinearIVUser(User *U,
Value *InnerTripCount,
200 SmallPtrSet<Value *, 4> &ValidOuterPHIUses) {
201 LLVM_DEBUG(
dbgs() <<
"Checking linear i*M+j expression for: ";
U->dump());
202 Value *MatchedMul =
nullptr;
203 Value *MatchedItCount =
nullptr;
233 return !isInstructionTriviallyDead(cast<Instruction>(U));
241 if (Widened && (IsAdd || IsGEP) &&
243 assert(MatchedItCount->
getType() == InnerInductionPHI->getType() &&
244 "Unexpected type mismatch in types after widening");
251 InnerTripCount->dump());
253 if ((IsAdd || IsAddTrunc || IsGEP) && MatchedItCount == InnerTripCount) {
255 ValidOuterPHIUses.
insert(MatchedMul);
256 LinearIVUses.insert(U);
260 LLVM_DEBUG(
dbgs() <<
"Did not match expected pattern, bailing\n");
264 bool checkInnerInductionPhiUsers(SmallPtrSet<Value *, 4> &ValidOuterPHIUses) {
265 Value *SExtInnerTripCount = InnerTripCount;
270 for (User *U : InnerInductionPHI->users()) {
272 if (isInnerLoopIncrement(U)) {
273 LLVM_DEBUG(
dbgs() <<
"Use is inner loop increment, continuing\n");
282 U = *
U->user_begin();
289 if (isInnerLoopTest(U)) {
294 if (!matchLinearIVUser(U, SExtInnerTripCount, ValidOuterPHIUses)) {
328 LLVM_DEBUG(
dbgs() <<
"Backedge-taken count is not predictable\n");
335 const SCEV *SCEVTripCount =
337 BackedgeTakenCount->
getType(), L);
340 if (SCEVRHS == SCEVTripCount)
344 const SCEV *BackedgeTCExt =
nullptr;
346 const SCEV *SCEVTripCountExt;
352 if (SCEVRHS != BackedgeTCExt && SCEVRHS != SCEVTripCountExt) {
359 if (SCEVRHS == BackedgeTCExt || SCEVRHS == BackedgeTakenCount) {
363 IterationInstructions);
375 if (!TripCountInst) {
380 SE->
getSCEV(TripCountInst->getOperand(0)) != SCEVTripCount) {
381 LLVM_DEBUG(
dbgs() <<
"Could not find valid extended trip count\n");
393 LLVM_DEBUG(
dbgs() <<
"Finding components of loop: " << L->getName() <<
"\n");
395 if (!L->isLoopSimplifyForm()) {
402 if (!L->isCanonical(*SE)) {
410 if (L->getExitingBlock() != Latch) {
418 InductionPHI = L->getInductionVariable(*SE);
435 ICmpInst *Compare = L->getLatchCmpInst();
436 if (!Compare || !IsValidPredicate(Compare->getUnsignedPredicate()) ||
437 Compare->hasNUsesOrMore(2)) {
442 IterationInstructions.
insert(BackBranch);
444 IterationInstructions.
insert(Compare);
463 Value *
RHS = Compare->getOperand(1);
485 SafeOuterPHIs.
insert(FI.OuterInductionPHI);
492 if (&InnerPHI == FI.InnerInductionPHI)
494 if (FI.isNarrowInductionPhi(&InnerPHI))
499 assert(InnerPHI.getNumIncomingValues() == 2);
500 Value *PreHeaderValue =
503 InnerPHI.getIncomingValueForBlock(FI.InnerLoop->
getLoopLatch());
529 dbgs() <<
"LCSSA PHI incoming value does not match latch value\n");
536 SafeOuterPHIs.
insert(OuterPHI);
537 FI.InnerPHIsToTransform.insert(&InnerPHI);
541 if (FI.isNarrowInductionPhi(&OuterPHI))
543 if (!SafeOuterPHIs.
count(&OuterPHI)) {
544 LLVM_DEBUG(
dbgs() <<
"found unsafe PHI in outer loop: "; OuterPHI.dump());
570 LLVM_DEBUG(
dbgs() <<
"Cannot flatten because instruction may have "
579 if (IterationInstructions.
count(&
I))
595 RepeatedInstrCost += Cost;
599 LLVM_DEBUG(
dbgs() <<
"Cost of instructions that will be repeated: "
600 << RepeatedInstrCost <<
"\n");
604 LLVM_DEBUG(
dbgs() <<
"checkOuterLoopInsts: not profitable, bailing.\n");
625 if (!FI.checkInnerInductionPhiUsers(ValidOuterPHIUses))
630 if (!FI.checkOuterInductionPhiUsers(ValidOuterPHIUses))
634 dbgs() <<
"Found " << FI.LinearIVUses.
size()
635 <<
" value(s) that can be replaced:\n";
636 for (
Value *V : FI.LinearIVUses) {
657 FI.InnerTripCount, FI.OuterTripCount,
664 for (
Value *GEPUser :
GEP->users()) {
675 if (
GEP->isInBounds() &&
676 GEPOperand->getType()->getIntegerBitWidth() >=
677 DL.getPointerTypeSizeInBits(
GEP->getType())) {
679 dbgs() <<
"use of linear IV would be UB if overflow occurred: ";
689 for (
Value *V : FI.LinearIVUses) {
691 if (
GEP->getNumIndices() == 1 && CheckGEP(
GEP,
GEP->getOperand(1)))
695 if (CheckGEP(
GEP, V))
707 FI.InnerInductionPHI, FI.InnerTripCount,
708 FI.InnerIncrement, FI.InnerBranch, SE, FI.Widened))
711 FI.OuterInductionPHI, FI.OuterTripCount,
712 FI.OuterIncrement, FI.OuterBranch, SE, FI.Widened))
730 if (FI.InnerInductionPHI->
getType() != FI.OuterInductionPHI->
getType())
753 LLVM_DEBUG(
dbgs() <<
"Checks all passed, doing the transformation\n");
759 Remark <<
"Flattened into outer loop";
763 if (!FI.NewTripCount) {
764 FI.NewTripCount = BinaryOperator::CreateMul(
765 FI.InnerTripCount, FI.OuterTripCount,
"flatten.tripcount",
768 FI.NewTripCount->
dump());
790 Term->eraseFromParent();
800 for (
Value *V : FI.LinearIVUses) {
801 Value *OuterValue = FI.OuterInductionPHI;
803 OuterValue = Builder.CreateTrunc(FI.OuterInductionPHI, V->
getType(),
815 Builder.CreateGEP(
GEP->getSourceElementType(),
Base, OuterValue,
817 GEP->isInBounds() && InnerGEP->isInBounds());
830 U->markLoopAsDeleted(*FI.InnerLoop, FI.InnerLoop->
getName());
831 LI->
erase(FI.InnerLoop);
849 auto &
DL = M->getDataLayout();
850 auto *InnerType = FI.InnerInductionPHI->
getType();
851 auto *OuterType = FI.OuterInductionPHI->
getType();
852 unsigned MaxLegalSize =
DL.getLargestLegalIntTypeSizeInBits();
853 auto *MaxLegalType =
DL.getLargestLegalIntType(M->getContext());
858 if (InnerType != OuterType ||
859 InnerType->getScalarSizeInBits() >= MaxLegalSize ||
860 MaxLegalType->getScalarSizeInBits() <
861 InnerType->getScalarSizeInBits() * 2) {
868 unsigned ElimExt = 0;
869 unsigned Widened = 0;
873 createWideIV(WideIV, LI, SE, Rewriter, DT, DeadInsts, ElimExt, Widened,
884 if (!CreateWideIV({FI.InnerInductionPHI, MaxLegalType,
false},
Deleted))
889 FI.InnerPHIsToTransform.insert(FI.InnerInductionPHI);
891 if (!CreateWideIV({FI.OuterInductionPHI, MaxLegalType,
false},
Deleted))
894 assert(Widened &&
"Widened IV expected");
898 FI.NarrowInnerInductionPHI = FI.InnerInductionPHI;
899 FI.NarrowOuterInductionPHI = FI.OuterInductionPHI;
911 dbgs() <<
"Loop flattening running on outer loop "
933 if (FI.Widened && !CanFlatten)
947 LLVM_DEBUG(
dbgs() <<
"Multiply would always overflow, so not profitable\n");
953 LLVM_DEBUG(
dbgs() <<
"Multiply might overflow, not flattening\n");
955 }
else if (!
DL.isLegalInteger(
961 dbgs() <<
"Can't check overflow efficiently, not flattening\n");
964 LLVM_DEBUG(
dbgs() <<
"Multiply might overflow, versioning loop\n");
978 "Expected LoopVersioning to generate a conditional branch");
980 "Expected branch condition to be false");
983 Intrinsic::umul_with_overflow, FI.OuterTripCount->
getType(),
984 {FI.OuterTripCount, FI.InnerTripCount},
985 nullptr,
"flatten.mul");
986 FI.NewTripCount = Builder.CreateExtractValue(
Call, 0,
"flatten.tripcount");
987 Value *Overflow = Builder.CreateExtractValue(
Call, 1,
"flatten.overflow");
990 LLVM_DEBUG(
dbgs() <<
"Multiply cannot overflow, modifying loop in-place\n");
1002 std::optional<MemorySSAUpdater> MSSAU;
1019 FlattenInfo FI(OuterLoop, InnerLoop);
1022 MSSAU ? &*MSSAU :
nullptr, LAIM.
getInfo(*OuterLoop));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
static bool CanWidenIV(FlattenInfo &FI, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, const TargetTransformInfo *TTI)
static bool verifyTripCount(Value *RHS, Loop *L, SmallPtrSetImpl< Instruction * > &IterationInstructions, PHINode *&InductionPHI, Value *&TripCount, BinaryOperator *&Increment, BranchInst *&BackBranch, ScalarEvolution *SE, bool IsWidened)
static cl::opt< bool > WidenIV("loop-flatten-widen-iv", cl::Hidden, cl::init(true), cl::desc("Widen the loop induction variables, if possible, so " "overflow checks won't reject flattening"))
static bool setLoopComponents(Value *&TC, Value *&TripCount, BinaryOperator *&Increment, SmallPtrSetImpl< Instruction * > &IterationInstructions)
static bool DoFlattenLoopPair(FlattenInfo &FI, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, const TargetTransformInfo *TTI, LPMUpdater *U, MemorySSAUpdater *MSSAU)
static bool FlattenLoopPair(FlattenInfo &FI, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, const TargetTransformInfo *TTI, LPMUpdater *U, MemorySSAUpdater *MSSAU, const LoopAccessInfo &LAI)
static bool checkIVUsers(FlattenInfo &FI)
static bool CanFlattenLoopPair(FlattenInfo &FI, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, const TargetTransformInfo *TTI)
static cl::opt< bool > VersionLoops("loop-flatten-version-loops", cl::Hidden, cl::init(true), cl::desc("Version loops if flattened loop could overflow"))
static bool findLoopComponents(Loop *L, SmallPtrSetImpl< Instruction * > &IterationInstructions, PHINode *&InductionPHI, Value *&TripCount, BinaryOperator *&Increment, BranchInst *&BackBranch, ScalarEvolution *SE, bool IsWidened)
static OverflowResult checkOverflow(FlattenInfo &FI, DominatorTree *DT, AssumptionCache *AC)
static bool checkPHIs(FlattenInfo &FI, const TargetTransformInfo *TTI)
static cl::opt< unsigned > RepeatedInstructionThreshold("loop-flatten-cost-threshold", cl::Hidden, cl::init(2), cl::desc("Limit on the cost of instructions that can be repeated due to " "loop flattening"))
static cl::opt< bool > AssumeNoOverflow("loop-flatten-assume-no-overflow", cl::Hidden, cl::init(false), cl::desc("Assume that the product of the two iteration " "trip counts will never overflow"))
static bool checkOuterLoopInsts(FlattenInfo &FI, SmallPtrSetImpl< Instruction * > &IterationInstructions, const TargetTransformInfo *TTI)
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Virtual Register Rewriter
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Conditional or Unconditional Branch instruction.
void setCondition(Value *V)
bool isConditional() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Value * getCondition() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_ULT
unsigned less than
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
A parsed version of the target data layout string in and methods for querying it.
void deleteEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge deletion and update the tree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
LLVM_ABI const LoopAccessInfo & getInfo(Loop &L, bool AllowPartial=false)
Drive the analysis of memory accesses in the loop.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
BlockT * getHeader() const
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
PreservedAnalyses run(LoopNest &LN, LoopAnalysisManager &LAM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
LLVM_ABI void erase(Loop *L)
Update LoopInfo after removing the last backedge from a loop.
This class represents a loop nest and can be used to query its properties.
ArrayRef< Loop * > getLoops() const
Get the loops in the nest.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
void versionLoop()
Performs the CFG manipulation part of versioning the loop including the DominatorTree and LoopInfo up...
Represents a single loop in the control flow graph.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
StringRef getName() const
An analysis that produces MemorySSA for a function.
LLVM_ABI void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
A Module instance is used to store all the information related to an LLVM module.
LLVM_ABI Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
LLVM_ABI Value * hasConstantValue() const
If the specified PHI node always merges together the same value, return the value,...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This class uses information about analyze scalars to rewrite expressions in canonical form.
This class represents an analyzed expression in the program.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
LLVM_ABI void forgetLoop(const Loop *L)
This method should be called by the client when it has changed a loop in a way that may effect Scalar...
LLVM_ABI const SCEV * getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
const ParentTy * getParent() const
self_iterator getIterator()
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_GEP(const OperandTypes &...Ops)
Matches GetElementPtrInst.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
@ NeverOverflows
Never overflows.
@ AlwaysOverflowsHigh
Always overflows in the direction of signed/unsigned max value.
@ AlwaysOverflowsLow
Always overflows in the direction of signed/unsigned min value.
@ MayOverflow
May or may not overflow.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
PHINode * createWideIV(const WideIVInfo &WI, LoopInfo *LI, ScalarEvolution *SE, SCEVExpander &Rewriter, DominatorTree *DT, SmallVectorImpl< WeakTrackingVH > &DeadInsts, unsigned &NumElimExt, unsigned &NumWidened, bool HasGuards, bool UsePostIncrementRanges)
Widen Induction Variables - Extend the width of an IV to cover its widest uses.
LLVM_ABI bool isGuaranteedToExecuteForEveryIteration(const Instruction *I, const Loop *L)
Return true if this function can prove that the instruction I is executed for every iteration of the ...
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
LLVM_ABI OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS, const SimplifyQuery &SQ, bool IsNSW=false)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
LLVM_ABI bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
If the specified value is an effectively dead PHI node, due to being a def-use chain of single-use no...
@ Increment
Incrementally increasing token ID.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI
Collect information about induction variables that are used by sign/zero extend operations.