60#define DEBUG_TYPE "loop-unroll-and-jam"
62STATISTIC(NumUnrolledAndJammed,
"Number of loops unroll and jammed");
63STATISTIC(NumCompletelyUnrolledAndJammed,
"Number of loops unroll and jammed");
71 Loop *SubLoop = L.getSubLoops()[0];
87 if (BB == SubLoopPreHeader)
91 if (!ForeBlocks.
count(Succ))
142 if (!VisitedInstr.
insert(
I).second)
145 if (AftBlocks.
count(
I->getParent()))
146 for (
auto &U :
I->operands())
148 if (!ProcessInstr(
II))
154 for (
auto &Phi : Header->phis()) {
155 Value *V = Phi.getIncomingValueForBlock(Latch);
157 if (!ProcessInstr(
I))
173 if (AftBlocks.
count(
I->getParent()))
174 I->moveBefore(InsertLoc);
215 unsigned TripMultiple,
bool UnrollRemainder,
222 assert(Header &&
"No header.");
223 assert(L->getSubLoops().size() == 1);
224 Loop *SubLoop = *L->begin();
227 if (TripCount == 0 &&
Count < 2) {
228 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; almost nothing to do\n");
234 assert(TripCount == 0 || TripCount % TripMultiple == 0);
237 bool CompletelyUnroll = (
Count == TripCount);
240 if (TripMultiple %
Count != 0) {
243 UnrollRemainder,
false,
244 LI, SE, DT, AC,
TTI,
true,
246 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; remainder loop could not be "
247 "generated when assuming runtime trip count\n");
261 if (CompletelyUnroll) {
263 << Header->getName() <<
" with trip count " << TripCount
267 <<
"completely unroll and jammed loop with "
268 << NV(
"UnrollCount", TripCount) <<
" iterations");
270 auto DiagBuilder = [&]() {
273 return Diag <<
"unroll and jammed loop by a factor of "
274 << NV(
"UnrollCount",
Count);
277 LLVM_DEBUG(
dbgs() <<
"UNROLL AND JAMMING loop %" << Header->getName()
279 if (TripMultiple != 1) {
280 LLVM_DEBUG(
dbgs() <<
" with " << TripMultiple <<
" trips per branch");
282 return DiagBuilder() <<
" with " << NV(
"TripMultiple", TripMultiple)
283 <<
" trips per branch";
287 ORE->
emit([&]() {
return DiagBuilder() <<
" with run-time trip count"; });
292 BasicBlock *Preheader = L->getLoopPreheader();
294 assert(Preheader &&
"No preheader");
295 assert(LatchBlock &&
"No latch block");
299 bool SubLoopContinueOnTrue = SubLoop->
contains(
313 std::vector<BasicBlock *> ForeBlocksFirst;
314 std::vector<BasicBlock *> ForeBlocksLast;
315 std::vector<BasicBlock *> SubLoopBlocksFirst;
316 std::vector<BasicBlock *> SubLoopBlocksLast;
317 std::vector<BasicBlock *> AftBlocksFirst;
318 std::vector<BasicBlock *> AftBlocksLast;
319 ForeBlocksFirst.push_back(Header);
321 SubLoopBlocksFirst.push_back(SubLoop->
getHeader());
324 AftBlocksLast.push_back(L->getExitingBlock());
330 Header, LatchBlock, ForeBlocksLast[0]->getTerminator()->getIterator(),
344 if (Header->getParent()->shouldEmitDebugInfoForProfiling() &&
348 if (!
I.isDebugOrPseudoInst())
350 auto NewDIL = DIL->cloneByMultiplyingDuplicationFactor(
Count);
352 I.setDebugLoc(*NewDIL);
355 <<
"Failed to create new discriminator: "
356 << DIL->getFilename() <<
" Line: " << DIL->getLine());
360 for (
unsigned It = 1; It !=
Count; ++It) {
366 NewLoops[SubLoop] = SubLoop;
371 Header->getParent()->insert(Header->getParent()->end(), New);
376 if (ForeBlocks.
count(*BB)) {
377 if (*BB == ForeBlocksFirst[0])
378 ForeBlocksFirst.push_back(New);
379 if (*BB == ForeBlocksLast[0])
380 ForeBlocksLast.push_back(New);
381 }
else if (SubLoopBlocks.
count(*BB)) {
382 if (*BB == SubLoopBlocksFirst[0])
383 SubLoopBlocksFirst.push_back(New);
384 if (*BB == SubLoopBlocksLast[0])
385 SubLoopBlocksLast.push_back(New);
386 }
else if (AftBlocks.
count(*BB)) {
387 if (*BB == AftBlocksFirst[0])
388 AftBlocksFirst.push_back(New);
389 if (*BB == AftBlocksLast[0])
390 AftBlocksLast.push_back(New);
396 auto &
Last = LastValueMap[*BB];
397 PrevItValueMap[New] = (It == 1 ? *BB :
Last);
401 auto &LVM = LastValueMap[VI->first];
402 PrevItValueMap[VI->second] =
403 const_cast<Value *
>(It == 1 ? VI->first : LVM);
410 if (*BB == ForeBlocksFirst[0])
412 else if (*BB == SubLoopBlocksFirst[0])
414 else if (*BB == AftBlocksFirst[0])
419 auto BBDomNode = DT->
getNode(*BB);
420 auto BBIDom = BBDomNode->
getIDom();
421 BasicBlock *OriginalBBIDom = BBIDom->getBlock();
440 for (
PHINode &Phi : ForeBlocksFirst[It]->phis()) {
441 Value *OldValue = Phi.getIncomingValueForBlock(AftBlocksLast[It]);
442 assert(OldValue &&
"should have incoming edge from Aft[It]");
443 Value *NewValue = OldValue;
444 if (
Value *PrevValue = PrevItValueMap[OldValue])
445 NewValue = PrevValue;
447 assert(Phi.getNumOperands() == 2);
448 Phi.setIncomingBlock(0, ForeBlocksLast[It - 1]);
449 Phi.setIncomingValue(0, NewValue);
450 Phi.removeIncomingValue(1);
463 for (
PHINode &Phi : BB->phis()) {
464 for (
unsigned b = 0; b < Phi.getNumIncomingValues(); ++b) {
465 if (Phi.getIncomingBlock(b) == OldBB) {
466 Value *OldValue = Phi.getIncomingValue(b);
467 if (
Value *LastValue = LastValueMap[OldValue])
468 Phi.setIncomingValue(b, LastValue);
469 Phi.setIncomingBlock(b, NewBB);
479 Phi->moveBefore(*Dest, insertPoint);
483 updatePHIBlocksAndValues(LoopExit, AftBlocksLast[0], AftBlocksLast.back(),
491 if (CompletelyUnroll) {
493 Phi->replaceAllUsesWith(Phi->getIncomingValueForBlock(Preheader));
494 Phi->eraseFromParent();
498 updatePHIBlocksAndValues(ForeBlocksFirst[0], AftBlocksLast[0],
499 AftBlocksLast.back(), LastValueMap);
502 for (
unsigned It = 1; It !=
Count; It++) {
512 SubTerm->
setSuccessor(!SubLoopContinueOnTrue, SubLoopBlocksFirst[0]);
513 SubTerm->
setSuccessor(SubLoopContinueOnTrue, AftBlocksFirst[0]);
514 SubLoopBlocksFirst[0]->replacePhiUsesWith(ForeBlocksLast[0],
515 ForeBlocksLast.back());
516 SubLoopBlocksFirst[0]->replacePhiUsesWith(SubLoopBlocksLast[0],
517 SubLoopBlocksLast.back());
519 for (
unsigned It = 1; It !=
Count; It++) {
527 SubLoopBlocksFirst[It]->replacePhiUsesWith(ForeBlocksLast[It],
528 ForeBlocksLast.back());
529 SubLoopBlocksFirst[It]->replacePhiUsesWith(SubLoopBlocksLast[It],
530 SubLoopBlocksLast.back());
531 movePHIs(SubLoopBlocksFirst[It], SubLoopBlocksFirst[0]);
536 if (CompletelyUnroll) {
540 AftTerm->
setSuccessor(!ContinueOnTrue, ForeBlocksFirst[0]);
542 "Expecting the ContinueOnTrue successor of AftTerm to be LoopExit");
544 AftBlocksFirst[0]->replacePhiUsesWith(SubLoopBlocksLast[0],
545 SubLoopBlocksLast.back());
547 for (
unsigned It = 1; It !=
Count; It++) {
555 AftBlocksFirst[It]->replacePhiUsesWith(SubLoopBlocksLast[It],
556 SubLoopBlocksLast.back());
557 movePHIs(AftBlocksFirst[It], AftBlocksFirst[0]);
565 DTUpdates.
emplace_back(DominatorTree::UpdateKind::Delete, ForeBlocksLast[0],
566 SubLoopBlocksFirst[0]);
567 DTUpdates.
emplace_back(DominatorTree::UpdateKind::Delete,
568 SubLoopBlocksLast[0], AftBlocksFirst[0]);
570 DTUpdates.
emplace_back(DominatorTree::UpdateKind::Insert,
571 ForeBlocksLast.back(), SubLoopBlocksFirst[0]);
572 DTUpdates.
emplace_back(DominatorTree::UpdateKind::Insert,
573 SubLoopBlocksLast.back(), AftBlocksFirst[0]);
589 std::vector<BasicBlock *> Blocks = L->getBlocks();
590 if (CompletelyUnroll) {
603 NumCompletelyUnrolledAndJammed += CompletelyUnroll;
604 ++NumUnrolledAndJammed;
616 if (!CompletelyUnroll)
617 assert(L->isLoopSimplifyForm());
640 }
else if (
I.mayReadOrWriteMemory()) {
649 unsigned UnrollLevel,
unsigned JamLevel,
653 for (
unsigned CurLoopDepth = UnrollLevel + 1; CurLoopDepth <= JamLevel;
655 auto JammedDir =
D->getDirection(CurLoopDepth);
667 unsigned UnrollLevel,
unsigned JamLevel,
670 for (
unsigned CurLoopDepth = UnrollLevel + 1; CurLoopDepth <= JamLevel;
672 auto JammedDir =
D->getDirection(CurLoopDepth);
681 return Sequentialized;
693 unsigned UnrollLevel,
unsigned JamLevel,
695 assert(UnrollLevel <= JamLevel &&
696 "Expecting JamLevel to be at least UnrollLevel");
714 std::unique_ptr<Dependence>
D = DI.
depends(Src, Dst);
717 assert(
D->isOrdered() &&
"Expected an output, flow or anti dep.");
719 if (
D->isConfused()) {
721 <<
" " << *Src <<
"\n"
722 <<
" " << *Dst <<
"\n");
730 for (
unsigned CurLoopDepth = 1; CurLoopDepth < UnrollLevel; ++CurLoopDepth)
734 auto UnrollDirection =
D->getDirection(UnrollLevel);
744 Sequentialized,
D.get()))
749 Sequentialized,
D.get()))
773 CurrentLoadsAndStores.
clear();
777 Loop *CurLoop = LI.
getLoopFor((*Blocks.begin())->front().getParent());
780 for (
auto *Earlier : EarlierLoadsAndStores) {
783 unsigned CommonLoopDepth = std::min(EarlierDepth, CurLoopDepth);
784 for (
auto *Later : CurrentLoadsAndStores) {
785 if (!
checkDependency(Earlier, Later, LoopDepth, CommonLoopDepth,
false,
791 size_t NumInsts = CurrentLoadsAndStores.
size();
792 for (
size_t I = 0;
I < NumInsts; ++
I) {
793 for (
size_t J =
I; J < NumInsts; ++J) {
795 LoopDepth, CurLoopDepth,
true, DI))
800 EarlierLoadsAndStores.append(CurrentLoadsAndStores.
begin(),
801 CurrentLoadsAndStores.
end());
811 const Loop *L = &Root;
814 if (!L->isLoopSimplifyForm())
817 if (!L->isRotatedForm())
820 if (L->getHeader()->hasAddressTaken()) {
825 unsigned SubLoopsSize = L->getSubLoops().size();
826 if (SubLoopsSize == 0)
830 if (SubLoopsSize != 1)
837 if (!L->getExitBlock()) {
838 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; only loops with single exit "
839 "blocks can be unrolled and jammed.\n");
844 if (!L->getExitingBlock()) {
845 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; only loops with single "
846 "exiting blocks can be unrolled and jammed.\n");
850 L = L->getSubLoops()[0];
857 while (!L->getSubLoops().empty())
858 L = L->getSubLoops()[0];
865 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Ineligible loop form\n");
927 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Incompatible loop layout\n");
934 if (AftBlocksMap[L].
size() != 1) {
935 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Can't currently handle "
936 "multiple blocks after the loop\n");
942 if (
any_of(L->getLoopsInPreorder(), [&SE](
Loop *SubLoop) {
943 return !hasIterationCountInvariantInParent(SubLoop, SE);
945 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Inner loop iteration count is "
946 "not consistent on each iteration\n");
953 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Something may throw\n");
967 Loop *SubLoop = L->getSubLoops()[0];
969 Header, Latch, AftBlocks, [&AftBlocks, &SubLoop](
Instruction *
I) {
972 if (AftBlocks.
count(
I->getParent())) {
979 if (
I->mayHaveSideEffects() ||
I->mayReadOrWriteMemory())
986 "instructions after subloop to before it\n");
995 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; failed dependency check\n");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file defines the DenseMap class.
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
SmallPtrSet< BasicBlock *, 4 > BasicBlockSet
static bool partitionLoopBlocks(Loop &L, BasicBlockSet &ForeBlocks, BasicBlockSet &AftBlocks, DominatorTree &DT)
static void moveHeaderPhiOperandsToForeBlocks(BasicBlock *Header, BasicBlock *Latch, BasicBlock::iterator InsertLoc, BasicBlockSet &AftBlocks)
static Loop * getInnerMostLoop(Loop *L)
static bool getLoadsAndStores(BasicBlockSet &Blocks, SmallVector< Instruction *, 4 > &MemInstr)
static bool preservesForwardDependence(Instruction *Src, Instruction *Dst, unsigned UnrollLevel, unsigned JamLevel, bool Sequentialized, Dependence *D)
static bool partitionOuterLoopBlocks(Loop &Root, Loop &JamLoop, BasicBlockSet &JamLoopBlocks, DenseMap< Loop *, BasicBlockSet > &ForeBlocksMap, DenseMap< Loop *, BasicBlockSet > &AftBlocksMap, DominatorTree &DT)
Partition blocks in a loop nest into blocks before and after each inner loop.
static bool isEligibleLoopForm(const Loop &Root)
static bool preservesBackwardDependence(Instruction *Src, Instruction *Dst, unsigned UnrollLevel, unsigned JamLevel, bool Sequentialized, Dependence *D)
static bool checkDependencies(Loop &Root, const BasicBlockSet &SubLoopBlocks, const DenseMap< Loop *, BasicBlockSet > &ForeBlocksMap, const DenseMap< Loop *, BasicBlockSet > &AftBlocksMap, DependenceInfo &DI, LoopInfo &LI)
static bool processHeaderPhiOperands(BasicBlock *Header, BasicBlock *Latch, BasicBlockSet &AftBlocks, T Visit)
static bool checkDependency(Instruction *Src, Instruction *Dst, unsigned UnrollLevel, unsigned JamLevel, bool Sequentialized, DependenceInfo &DI)
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
uint64_t IntrinsicInst * II
This file defines the SmallPtrSet class.
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)
A cache of @llvm.assume calls within a function.
LLVM_ABI void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Conditional Branch instruction.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
BasicBlock * getSuccessor(unsigned i) const
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
DependenceInfo - This class is the main dependence-analysis driver.
LLVM_ABI std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool UnderRuntimeAssumptions=false)
depends - Tests for a dependence between the Src and Dst instructions.
Dependence - This class represents a dependence between two memory memory references in a function.
DomTreeNodeBase * getIDom() const
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
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.
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.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdatesPermissive(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
SmallVector< const LoopT *, 4 > getLoopsInPreorder() const
Return all loops in the loop nest rooted by the loop in preorder, with siblings in forward program or...
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
BlockT * getHeader() const
unsigned getLoopDepth() const
Return the nesting level of this loop.
iterator_range< block_iterator > blocks() 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.
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
LLVM_ABI 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.
LLVM_ABI void erase(Loop *L)
Update LoopInfo after removing the last backedge from a loop.
Represents a single loop in the control flow graph.
bool isLoopSimplifyForm() const
Return true if the Loop is in the form that the LoopSimplify form transforms loops to,...
bool isRecursivelyLCSSAForm(const DominatorTree &DT, const LoopInfo &LI, bool IgnoreTokens=true) const
Return true if this Loop and all inner subloops are in LCSSA form.
The main scalar evolution driver.
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 void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
LLVM_ABI void verify() const
Simple and conservative implementation of LoopSafetyInfo that can give false-positive answers to its ...
bool anyBlockMayThrow() const override
Returns true iff any block of the loop for which this info is contains an instruction that may throw ...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
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.
reference emplace_back(ArgTypes &&... Args)
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...
Unconditional Branch instruction.
void setSuccessor(BasicBlock *NewSucc)
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
ValueMapIteratorImpl< MapT, const Value *, false > iterator
LLVM Value Representation.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT, DependenceInfo &DI, LoopInfo &LI)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
LLVM_ABI void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, ArrayRef< BasicBlock * > Blocks, AAResults *AA=nullptr)
Perform some cleanup and simplifications on loops after unrolling.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool MergeBlockSuccessorsIntoGivenBlocks(SmallPtrSetImpl< BasicBlock * > &MergeBlocks, Loop *L=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
Merge block(s) sucessors, if possible.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI cl::opt< unsigned > SCEVCheapExpansionBudget
LoopUnrollResult
Represents the result of a UnrollLoop invocation.
@ PartiallyUnrolled
The loop was partially unrolled – we still have a loop, but with a smaller trip count.
@ Unmodified
The loop was not modified.
@ FullyUnrolled
The loop was fully unrolled into straight-line code.
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI const Loop * addClonedBlockToLoopInfo(BasicBlock *OriginalBB, BasicBlock *ClonedBB, LoopInfo *LI, NewLoopsMap &NewLoops)
Adds ClonedBB to LoopInfo, creates a new loop for ClonedBB if necessary and adds a mapping from the o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool UnrollRuntimeLoopRemainder(Loop *L, unsigned Count, bool AllowExpensiveTripCount, bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, bool PreserveLCSSA, unsigned SCEVExpansionBudget, bool RuntimeUnrollMultiExit, Loop **ResultLoop=nullptr, std::optional< unsigned > OriginalTripCount=std::nullopt, BranchProbability OriginalLoopProb=BranchProbability::getUnknown())
Insert code in the prolog/epilog code when unrolling a loop with a run-time trip-count.
LLVM_ABI LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount, unsigned TripMultiple, bool UnrollRemainder, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE, Loop **EpilogueLoop=nullptr)