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++) {
525 SubTerm->eraseFromParent();
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) {
538 AftTerm->eraseFromParent();
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++) {
553 AftTerm->eraseFromParent();
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]);
595 NumCompletelyUnrolledAndJammed += CompletelyUnroll;
596 ++NumUnrolledAndJammed;
599 if (CompletelyUnroll)
612 if (!CompletelyUnroll)
613 assert(L->isLoopSimplifyForm());
636 }
else if (
I.mayReadOrWriteMemory()) {
645 unsigned UnrollLevel,
unsigned JamLevel,
649 for (
unsigned CurLoopDepth = UnrollLevel + 1; CurLoopDepth <= JamLevel;
651 auto JammedDir =
D->getDirection(CurLoopDepth);
663 unsigned UnrollLevel,
unsigned JamLevel,
666 for (
unsigned CurLoopDepth = UnrollLevel + 1; CurLoopDepth <= JamLevel;
668 auto JammedDir =
D->getDirection(CurLoopDepth);
677 return Sequentialized;
689 unsigned UnrollLevel,
unsigned JamLevel,
691 assert(UnrollLevel <= JamLevel &&
692 "Expecting JamLevel to be at least UnrollLevel");
710 std::unique_ptr<Dependence>
D = DI.
depends(Src, Dst);
713 assert(
D->isOrdered() &&
"Expected an output, flow or anti dep.");
715 if (
D->isConfused()) {
717 <<
" " << *Src <<
"\n"
718 <<
" " << *Dst <<
"\n");
726 for (
unsigned CurLoopDepth = 1; CurLoopDepth < UnrollLevel; ++CurLoopDepth)
730 auto UnrollDirection =
D->getDirection(UnrollLevel);
740 Sequentialized,
D.get()))
745 Sequentialized,
D.get()))
769 CurrentLoadsAndStores.
clear();
773 Loop *CurLoop = LI.
getLoopFor((*Blocks.begin())->front().getParent());
776 for (
auto *Earlier : EarlierLoadsAndStores) {
779 unsigned CommonLoopDepth = std::min(EarlierDepth, CurLoopDepth);
780 for (
auto *Later : CurrentLoadsAndStores) {
781 if (!
checkDependency(Earlier, Later, LoopDepth, CommonLoopDepth,
false,
787 size_t NumInsts = CurrentLoadsAndStores.
size();
788 for (
size_t I = 0;
I < NumInsts; ++
I) {
789 for (
size_t J =
I; J < NumInsts; ++J) {
791 LoopDepth, CurLoopDepth,
true, DI))
796 EarlierLoadsAndStores.append(CurrentLoadsAndStores.
begin(),
797 CurrentLoadsAndStores.
end());
807 const Loop *L = &Root;
810 if (!L->isLoopSimplifyForm())
813 if (!L->isRotatedForm())
816 if (L->getHeader()->hasAddressTaken()) {
821 unsigned SubLoopsSize = L->getSubLoops().size();
822 if (SubLoopsSize == 0)
826 if (SubLoopsSize != 1)
833 if (!L->getExitBlock()) {
834 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; only loops with single exit "
835 "blocks can be unrolled and jammed.\n");
840 if (!L->getExitingBlock()) {
841 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; only loops with single "
842 "exiting blocks can be unrolled and jammed.\n");
846 L = L->getSubLoops()[0];
853 while (!L->getSubLoops().empty())
854 L = L->getSubLoops()[0];
861 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Ineligible loop form\n");
923 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Incompatible loop layout\n");
930 if (AftBlocksMap[L].
size() != 1) {
931 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Can't currently handle "
932 "multiple blocks after the loop\n");
938 if (
any_of(L->getLoopsInPreorder(), [&SE](
Loop *SubLoop) {
939 return !hasIterationCountInvariantInParent(SubLoop, SE);
941 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Inner loop iteration count is "
942 "not consistent on each iteration\n");
950 LLVM_DEBUG(
dbgs() <<
"Won't unroll-and-jam; Something may throw\n");
964 Loop *SubLoop = L->getSubLoops()[0];
966 Header, Latch, AftBlocks, [&AftBlocks, &SubLoop](
Instruction *
I) {
969 if (AftBlocks.
count(
I->getParent())) {
976 if (
I->mayHaveSideEffects() ||
I->mayReadOrWriteMemory())
983 "instructions after subloop to before it\n");
992 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 if the block is well formed or null if the block is not well forme...
Conditional Branch instruction.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
BasicBlock * getSuccessor(unsigned i) const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
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 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 in 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.
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
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
RPOIterator endRPO() const
void verify(const DominatorTreeBase< BlockT, false > &DomTree) 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 ...
void computeLoopSafetyInfo(const Loop *CurLoop) override
Computes safety information for a loop checks loop body & header for the possibility of may throw exc...
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.
static UncondBrInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
void setSuccessor(BasicBlock *NewSucc)
ValueMapIteratorImpl< MapT, const Value *, false > iterator
LLVM Value Representation.
#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)
LLVM_ABI void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, AAResults *AA=nullptr)
Perform some cleanup and simplifications on loops after unrolling.
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
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
FunctionAddr VTableAddr Count
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...
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)