49#define DEBUG_TYPE "loop-peel"
55 cl::desc(
"Set the unroll peeling count, for testing purposes"));
59 cl::desc(
"Allows loops to be peeled when the dynamic "
60 "trip count is known to be low."));
65 cl::desc(
"Allows loop nests to be peeled."));
69 cl::desc(
"Max average trip count which will cause loop peeling."));
73 cl::desc(
"Force a peel count regardless of profiling information."));
78 "Disable advance peeling. Issues for convergent targets (D134803)."));
85 if (!L->isLoopSimplifyForm())
91 L->getUniqueNonLatchExitBlocks(Exits);
159 PhiAnalyzer(
const Loop &L,
unsigned MaxIterations);
163 std::optional<unsigned> calculateIterationsToPeel();
166 using PeelCounter = std::optional<unsigned>;
167 const PeelCounter Unknown = std::nullopt;
170 PeelCounter addOne(PeelCounter PC)
const {
173 return (*PC + 1 <= MaxIterations) ? PeelCounter{*PC + 1} :
Unknown;
178 PeelCounter calculate(
const Value &);
181 const unsigned MaxIterations;
187PhiAnalyzer::PhiAnalyzer(
const Loop &L,
unsigned MaxIterations)
188 :
L(
L), MaxIterations(MaxIterations) {
190 assert(MaxIterations > 0 &&
"no peeling is allowed?");
207PhiAnalyzer::PeelCounter PhiAnalyzer::calculate(
const Value &V) {
209 auto I = IterationsToInvariance.find(&V);
210 if (
I != IterationsToInvariance.end())
215 IterationsToInvariance[&
V] =
Unknown;
217 if (
L.isLoopInvariant(&V))
219 return (IterationsToInvariance[&V] = 0);
220 if (
const PHINode *Phi = dyn_cast<PHINode>(&V)) {
221 if (
Phi->getParent() !=
L.getHeader()) {
223 assert(IterationsToInvariance[&V] ==
Unknown &&
"unexpected value saved");
227 Value *Input =
Phi->getIncomingValueForBlock(
L.getLoopLatch());
228 PeelCounter Iterations = calculate(*Input);
229 assert(IterationsToInvariance[Input] == Iterations &&
230 "unexpected value saved");
231 return (IterationsToInvariance[Phi] = addOne(Iterations));
234 if (isa<CmpInst>(
I) ||
I->isBinaryOp()) {
236 PeelCounter
LHS = calculate(*
I->getOperand(0));
239 PeelCounter
RHS = calculate(*
I->getOperand(1));
242 return (IterationsToInvariance[
I] = {std::max(*LHS, *RHS)});
246 return (IterationsToInvariance[
I] = calculate(*
I->getOperand(0)));
251 assert(IterationsToInvariance[&V] ==
Unknown &&
"unexpected value saved");
255std::optional<unsigned> PhiAnalyzer::calculateIterationsToPeel() {
256 unsigned Iterations = 0;
257 for (
auto &
PHI :
L.getHeader()->phis()) {
258 PeelCounter ToInvariance = calculate(
PHI);
260 assert(*ToInvariance <= MaxIterations &&
"bad result in phi analysis");
261 Iterations = std::max(Iterations, *ToInvariance);
262 if (Iterations == MaxIterations)
266 assert((Iterations <= MaxIterations) &&
"bad result in phi analysis");
267 return Iterations ? std::optional<unsigned>(Iterations) :
std::nullopt;
281 if (L.getExitingBlock())
287 L.getUniqueNonLatchExitBlocks(Exits);
304 if (
I.mayWriteToMemory())
307 auto Iter = LoadUsers.
find(&
I);
308 if (Iter != LoadUsers.
end()) {
309 for (
Value *U :
I.users())
316 if (
auto *LI = dyn_cast<LoadInst>(&
I)) {
317 Value *
Ptr = LI->getPointerOperand();
318 if (DT.
dominates(BB, Latch) && L.isLoopInvariant(
Ptr) &&
320 for (
Value *U :
I.users())
326 L.getExitingBlocks(ExitingBlocks);
345 assert(L.isLoopSimplifyForm() &&
"Loop needs to be in loop simplify form");
346 unsigned DesiredPeelCount = 0;
350 if (
const SCEVConstant *SC = dyn_cast<SCEVConstant>(BE))
352 std::min((
unsigned)SC->getAPInt().getLimitedValue() - 1, MaxPeelCount);
357 auto PeelWhilePredicateIsKnown =
358 [&](
unsigned &PeelCount,
const SCEV *&IterVal,
const SCEV *BoundSCEV,
360 while (PeelCount < MaxPeelCount &&
370 std::function<void(
Value *,
unsigned)> ComputePeelCount =
371 [&](
Value *Condition,
unsigned Depth) ->
void {
375 Value *LeftVal, *RightVal;
378 ComputePeelCount(LeftVal,
Depth + 1);
379 ComputePeelCount(RightVal,
Depth + 1);
397 if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
398 if (isa<SCEVAddRecExpr>(RightSCEV)) {
400 Pred = ICmpInst::getSwappedPredicate(Pred);
417 unsigned NewPeelCount = DesiredPeelCount;
426 Pred = ICmpInst::getInversePredicate(Pred);
429 if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, RightSCEV, Step,
442 if (NewPeelCount >= MaxPeelCount)
447 DesiredPeelCount = std::max(DesiredPeelCount, NewPeelCount);
451 if (!
MinMax->getType()->isIntegerTy())
454 const SCEV *BoundSCEV, *IterSCEV;
455 if (L.isLoopInvariant(
LHS)) {
458 }
else if (L.isLoopInvariant(
RHS)) {
463 const auto *AddRec = dyn_cast<SCEVAddRecExpr>(IterSCEV);
465 if (!AddRec || !AddRec->isAffine() || AddRec->getLoop() != &L)
467 const SCEV *Step = AddRec->getStepRecurrence(SE);
468 bool IsSigned =
MinMax->isSigned();
473 Pred = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
475 Pred = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
479 if (!(IsSigned ? AddRec->hasNoSignedWrap() : AddRec->hasNoUnsignedWrap()))
481 unsigned NewPeelCount = DesiredPeelCount;
482 const SCEV *IterVal = AddRec->evaluateAtIteration(
483 SE.
getConstant(AddRec->getType(), NewPeelCount), SE);
484 if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, BoundSCEV, Step,
487 DesiredPeelCount = NewPeelCount;
493 ComputePeelCount(SI->getCondition(), 0);
495 ComputePeelCountMinMax(
MinMax);
498 auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
499 if (!BI || BI->isUnconditional())
503 if (L.getLoopLatch() == BB)
506 ComputePeelCount(BI->getCondition(), 0);
509 return DesiredPeelCount;
522 if (!LatchBR || LatchBR->
getNumSuccessors() != 2 || !L->isLoopExiting(Latch))
527 "At least one edge out of the latch must go to the header");
530 L->getUniqueNonLatchExitBlocks(ExitBlocks);
542 unsigned Threshold) {
543 assert(LoopSize > 0 &&
"Zero loop size is not allowed!");
561 <<
" iterations.\n");
572 if (2 * LoopSize > Threshold)
575 unsigned AlreadyPeeled = 0;
577 AlreadyPeeled = *Peeled;
584 MaxPeelCount = std::min(MaxPeelCount, Threshold / LoopSize - 1);
588 unsigned DesiredPeelCount = TargetPeelCount;
595 if (MaxPeelCount > DesiredPeelCount) {
597 auto NumPeels = PhiAnalyzer(*L, MaxPeelCount).calculateIterationsToPeel();
599 DesiredPeelCount = std::max(DesiredPeelCount, *NumPeels);
602 DesiredPeelCount = std::max(DesiredPeelCount,
605 if (DesiredPeelCount == 0)
608 if (DesiredPeelCount > 0) {
609 DesiredPeelCount = std::min(DesiredPeelCount, MaxPeelCount);
611 assert(DesiredPeelCount > 0 &&
"Wrong loop size estimation?");
614 <<
" iteration(s) to turn"
615 <<
" some Phis into invariants.\n");
635 if (L->getHeader()->getParent()->hasProfileData()) {
639 if (!EstimatedTripCount)
643 << *EstimatedTripCount <<
"\n");
645 if (*EstimatedTripCount) {
646 if (*EstimatedTripCount + AlreadyPeeled <= MaxPeelCount) {
647 unsigned PeelCount = *EstimatedTripCount;
648 LLVM_DEBUG(
dbgs() <<
"Peeling first " << PeelCount <<
" iterations.\n");
652 LLVM_DEBUG(
dbgs() <<
"Already peel count: " << AlreadyPeeled <<
"\n");
657 << (Threshold / LoopSize - 1) <<
"\n");
692 ? std::max(
Info.Weights[
Idx] - SubWeight, SubWeight)
700 L->getExitingBlocks(ExitingBlocks);
701 for (
BasicBlock *ExitingBlock : ExitingBlocks) {
712 if (L->contains(Succ))
713 FallThroughWeights += Weight;
715 ExitWeights += Weight;
719 if (FallThroughWeights == 0)
724 if (!L->contains(Succ)) {
732 double W = (double)Weight / (
double)FallThroughWeights;
736 WeightInfos.
insert({Term, {std::move(Weights), std::move(SubWeights)}});
759 BasicBlock *PreHeader = L->getLoopPreheader();
764 Loop *ParentLoop = L->getParentLoop();
796 std::string Ext = (
Twine(
"Peel") +
Twine(IterNumber)).str();
798 Header->getContext(), Ext);
803 for (
Loop *ChildLoop : *L) {
804 cloneLoop(ChildLoop, ParentLoop, VMap, LI,
nullptr);
818 BasicBlock *NewLatch = cast<BasicBlock>(VMap[Latch]);
819 auto *LatchTerm = cast<Instruction>(NewLatch->
getTerminator());
820 for (
unsigned idx = 0, e = LatchTerm->getNumSuccessors(); idx < e; ++idx)
821 if (LatchTerm->getSuccessor(idx) == Header) {
822 LatchTerm->setSuccessor(idx, InsertBot);
837 PHINode *NewPHI = cast<PHINode>(VMap[&*
I]);
838 if (IterNumber == 0) {
842 Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
843 if (LatchInst && L->contains(LatchInst))
844 VMap[&*
I] = LVMap[LatchInst];
846 VMap[&*
I] = LatchVal;
855 for (
auto Edge : ExitEdges)
857 Value *LatchVal =
PHI.getIncomingValueForBlock(Edge.first);
858 Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
859 if (LatchInst && L->contains(LatchInst))
860 LatchVal = VMap[LatchVal];
861 PHI.addIncoming(LatchVal, cast<BasicBlock>(VMap[Edge.first]));
868 LVMap[KV.first] = KV.second;
874 std::optional<bool> UserAllowPeeling,
875 std::optional<bool> UserAllowProfileBasedPeeling,
876 bool UnrollingSpecficValues) {
889 if (UnrollingSpecficValues) {
899 if (UserAllowPeeling)
901 if (UserAllowProfileBasedPeeling)
919 assert(PeelCount > 0 &&
"Attempt to peel out zero iterations?");
920 assert(
canPeel(L) &&
"Attempt to peel a loop which is not peelable?");
926 BasicBlock *PreHeader = L->getLoopPreheader();
929 L->getExitEdges(ExitEdges);
936 for (
auto *BB : L->blocks()) {
937 auto *BBDomNode = DT.
getNode(BB);
939 for (
auto *ChildDomNode : BBDomNode->children()) {
940 auto *ChildBB = ChildDomNode->getBlock();
941 if (!L->contains(ChildBB))
949 for (
auto *ChildBB : ChildrenToUpdate)
950 NonLoopBlocksIDom[ChildBB] = NewIDom;
1006 InsertTop->
setName(Header->getName() +
".peel.begin");
1007 InsertBot->
setName(Header->getName() +
".peel.next");
1011 cast<Instruction>(cast<BasicBlock>(Latch)->getTerminator());
1024 for (
unsigned Iter = 0; Iter < PeelCount; ++Iter) {
1029 LoopBlocks, VMap, LVMap, &DT, LI,
1030 LoopLocalNoAliasDeclScopes, *SE);
1038 for (
auto BBIDom : NonLoopBlocksIDom)
1040 cast<BasicBlock>(LVMap[BBIDom.second]));
1041#ifdef EXPENSIVE_CHECKS
1042 assert(DT.
verify(DominatorTree::VerificationLevel::Fast));
1045 for (
auto &[Term,
Info] : Weights) {
1046 auto *TermCopy = cast<Instruction>(VMap[Term]);
1052 auto *LatchTermCopy = cast<Instruction>(VMap[LatchTerm]);
1053 LatchTermCopy->setMetadata(LLVMContext::MD_loop,
nullptr);
1055 InsertTop = InsertBot;
1057 InsertBot->
setName(Header->getName() +
".peel.next");
1059 F->splice(InsertTop->
getIterator(),
F, NewBlocks[0]->getIterator(),
1067 Value *NewVal =
PHI->getIncomingValueForBlock(Latch);
1068 Instruction *LatchInst = dyn_cast<Instruction>(NewVal);
1069 if (LatchInst && L->contains(LatchInst))
1070 NewVal = LVMap[LatchInst];
1072 PHI->setIncomingValueForBlock(NewPreHeader, NewVal);
1075 for (
const auto &[Term,
Info] : Weights) {
1080 unsigned AlreadyPeeled = 0;
1082 AlreadyPeeled = *Peeled;
1085 if (
Loop *ParentLoop = L->getParentLoop())
1092#ifdef EXPENSIVE_CHECKS
1094 assert(DT.
verify(DominatorTree::VerificationLevel::Fast));
1098 simplifyLoop(L, &DT, LI, SE, AC,
nullptr, PreserveLCSSA);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static const unsigned MaxDepth
static void updateBranchWeights(Instruction *Term, WeightInfo &Info)
Update the branch weights of an exiting block of a peeled-off loop iteration.
static cl::opt< bool > DisableAdvancedPeeling("disable-advanced-peeling", cl::init(false), cl::Hidden, cl::desc("Disable advance peeling. Issues for convergent targets (D134803)."))
static cl::opt< unsigned > UnrollPeelMaxCount("unroll-peel-max-count", cl::init(7), cl::Hidden, cl::desc("Max average trip count which will cause loop peeling."))
static cl::opt< bool > UnrollAllowPeeling("unroll-allow-peeling", cl::init(true), cl::Hidden, cl::desc("Allows loops to be peeled when the dynamic " "trip count is known to be low."))
static cl::opt< unsigned > UnrollForcePeelCount("unroll-force-peel-count", cl::init(0), cl::Hidden, cl::desc("Force a peel count regardless of profiling information."))
static unsigned countToEliminateCompares(Loop &L, unsigned MaxPeelCount, ScalarEvolution &SE)
static bool violatesLegacyMultiExitLoopCheck(Loop *L)
This "heuristic" exactly matches implicit behavior which used to exist inside getLoopEstimatedTripCou...
static const char * PeeledCountMetaData
static void cloneLoopBlocks(Loop *L, unsigned IterNumber, BasicBlock *InsertTop, BasicBlock *InsertBot, SmallVectorImpl< std::pair< BasicBlock *, BasicBlock * > > &ExitEdges, SmallVectorImpl< BasicBlock * > &NewBlocks, LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap, ValueToValueMapTy &LVMap, DominatorTree *DT, LoopInfo *LI, ArrayRef< MDNode * > LoopLocalNoAliasDeclScopes, ScalarEvolution &SE)
Clones the body of the loop L, putting it between InsertTop and InsertBot.
static cl::opt< bool > UnrollAllowLoopNestsPeeling("unroll-allow-loop-nests-peeling", cl::init(false), cl::Hidden, cl::desc("Allows loop nests to be peeled."))
static cl::opt< unsigned > UnrollPeelCount("unroll-peel-count", cl::Hidden, cl::desc("Set the unroll peeling count, for testing purposes"))
static unsigned peelToTurnInvariantLoadsDerefencebale(Loop &L, DominatorTree &DT, AssumptionCache *AC)
static void initBranchWeights(DenseMap< Instruction *, WeightInfo > &WeightInfos, Loop *L)
Initialize the weights for all exiting blocks.
This file contains the declarations for profiling metadata utility functions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
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.
const CallInst * getTerminatingDeoptimizeCall() const
Returns the call instruction calling @llvm.experimental.deoptimize prior to the terminating return in...
InstListType::iterator iterator
Instruction iterators...
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.
unsigned getNumSuccessors() const
BasicBlock * getSuccessor(unsigned i) const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
A parsed version of the target data layout string in and methods for querying it.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DomTreeNodeBase * getIDom() const
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
bool isEquality() const
Return true if this predicate is either EQ or NE.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
Store the result of a depth first search within basic blocks contained by a single loop.
RPOIterator beginRPO() const
Reverse iterate over the cached postorder blocks.
std::vector< BasicBlock * >::const_reverse_iterator RPOIterator
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
RPOIterator endRPO() const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
This class represents min/max intrinsics.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
This node represents a polynomial recurrence on the trip count of the specified loop.
const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
This class represents a constant integer value.
bool hasNoSelfWrap() const
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const SCEV * getConstantMaxBackedgeTakenCount(const Loop *L)
When successful, this returns a SCEVConstant that is greater than or equal to (i.e.
bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
const SCEV * getConstant(ConstantInt *V)
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
std::optional< bool > evaluatePredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
Check whether the condition described by Pred, LHS, and RHS is true or false.
bool isKnownPositive(const SCEV *S)
Test if the given expression is known to be positive.
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
void forgetTopmostLoop(const Loop *L)
void forgetValue(Value *V)
This method should be called by the client when it has changed a value in a way that may effect its v...
void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
std::optional< MonotonicPredicateType > getMonotonicPredicateType(const SCEVAddRecExpr *LHS, ICmpInst::Predicate Pred)
If, for all loop invariant X, the predicate "LHS `Pred` X" is monotonically increasing or decreasing,...
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
This class represents the LLVM 'select' instruction.
iterator find(ConstPtrType Ptr) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void setName(const Twine &Name)
Change the name of the value.
StringRef getName() const
Return a constant reference to the value's name.
self_iterator getIterator()
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
initializer< Ty > init(const Ty &Val)
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
Simplify each loop in a loop nest recursively.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
std::optional< unsigned > getLoopEstimatedTripCount(Loop *L, unsigned *EstimatedLoopInvocationWeight=nullptr)
Returns a loop's estimated trip count based on branch weight metadata.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool IsBlockFollowedByDeoptOrUnreachable(const BasicBlock *BB)
Check if we can prove that all paths starting from this block converge to a block that either has a @...
void computePeelCount(Loop *L, unsigned LoopSize, TargetTransformInfo::PeelingPreferences &PP, unsigned TripCount, DominatorTree &DT, ScalarEvolution &SE, AssumptionCache *AC=nullptr, unsigned Threshold=UINT_MAX)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
auto successors(const MachineBasicBlock *BB)
bool canPeel(const Loop *L)
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V=0)
Set input string into loop metadata by keeping other values intact.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
TargetTransformInfo::PeelingPreferences gatherPeelingPreferences(Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI, std::optional< bool > UserAllowPeeling, std::optional< bool > UserAllowProfileBasedPeeling, bool UnrollingSpecficValues=false)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::optional< int > getOptionalIntLoopAttribute(const Loop *TheLoop, StringRef Name)
Find named metadata for a loop with an integer value.
void cloneAndAdaptNoAliasScopes(ArrayRef< MDNode * > NoAliasDeclScopes, ArrayRef< BasicBlock * > NewBlocks, LLVMContext &Context, StringRef Ext)
Clone the specified noalias decl scopes.
void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
bool isDereferenceablePointer(const Value *V, Type *Ty, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if this is always a dereferenceable pointer.
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
void identifyNoAliasScopesToClone(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< MDNode * > &NoAliasDeclScopes)
Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified basic blocks and extract ...
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
bool peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI, ScalarEvolution *SE, DominatorTree &DT, AssumptionCache *AC, bool PreserveLCSSA, ValueToValueMapTy &VMap)
VMap is the value-map that maps instructions from the original loop to instructions in the last peele...
Loop * cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM, LoopInfo *LI, LPPassManager *LPM)
Recursively clone the specified loop and all of its children, mapping the blocks with the specified m...
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SmallVector< uint32_t > Weights
const SmallVector< uint32_t > SubWeights