78 #define LDIST_NAME "loop-distribute" 79 #define DEBUG_TYPE LDIST_NAME 84 "llvm.loop.distribute.followup_all";
86 "llvm.loop.distribute.followup_coincident";
88 "llvm.loop.distribute.followup_sequential";
90 "llvm.loop.distribute.followup_fallback";
95 cl::desc(
"Turn on DominatorTree and LoopInfo verification " 96 "after Loop Distribution"),
100 "loop-distribute-non-if-convertible",
cl::Hidden,
101 cl::desc(
"Whether to distribute into a loop that may not be " 102 "if-convertible by the loop vectorizer"),
107 cl::desc(
"The maximum number of SCEV checks allowed for Loop " 111 "loop-distribute-scev-check-threshold-with-pragma",
cl::init(128),
114 "The maximum number of SCEV checks allowed for Loop " 115 "Distribution for loop marked with #pragma loop distribute(enable)"));
119 cl::desc(
"Enable the new, experimental LoopDistribution Pass"),
122 STATISTIC(NumLoopsDistributed,
"Number of loops distributed");
128 class InstPartition {
133 : DepCycle(DepCycle), OrigLoop(L) {
138 bool hasDepCycle()
const {
return DepCycle; }
144 InstructionSet::iterator
begin() {
return Set.
begin(); }
145 InstructionSet::iterator
end() {
return Set.
end(); }
146 InstructionSet::const_iterator
begin()
const {
return Set.
begin(); }
147 InstructionSet::const_iterator
end()
const {
return Set.
end(); }
148 bool empty()
const {
return Set.empty(); }
152 void moveTo(InstPartition &Other) {
153 Other.Set.insert(Set.begin(), Set.end());
155 Other.DepCycle |= DepCycle;
160 void populateUsedSet() {
164 for (
auto *
B : OrigLoop->getBlocks())
165 Set.insert(
B->getTerminator());
170 while (!Worklist.empty()) {
175 if (I && OrigLoop->contains(I->
getParent()) && Set.insert(I).second)
176 Worklist.push_back(I);
190 LI, DT, ClonedLoopBlocks);
196 const Loop *getClonedLoop()
const {
return ClonedLoop; }
201 Loop *getDistributedLoop()
const {
202 return ClonedLoop ? ClonedLoop : OrigLoop;
210 void remapInstructions() {
216 void removeUnusedInsts() {
219 for (
auto *Block : OrigLoop->getBlocks())
220 for (
auto &Inst : *Block)
221 if (!Set.count(&Inst)) {
224 NewInst = cast<Instruction>(VMap[NewInst]);
226 assert(!isa<BranchInst>(NewInst) &&
227 "Branches are marked used early on");
233 for (
auto *Inst :
reverse(Unused)) {
234 if (!Inst->use_empty())
236 Inst->eraseFromParent();
242 dbgs() <<
" (cycle)\n";
248 void printBlocks()
const {
249 for (
auto *BB : getDistributedLoop()->getBlocks())
265 Loop *ClonedLoop =
nullptr;
279 class InstPartitionContainer {
284 : L(L), LI(LI), DT(DT) {}
287 unsigned getSize()
const {
return PartitionContainer.size(); }
293 if (PartitionContainer.empty() || !PartitionContainer.back().hasDepCycle())
294 PartitionContainer.emplace_back(Inst, L,
true);
296 PartitionContainer.back().add(Inst);
304 void addToNewNonCyclicPartition(
Instruction *Inst) {
305 PartitionContainer.emplace_back(Inst, L);
313 void mergeAdjacentNonCyclic() {
314 mergeAdjacentPartitionsIf(
315 [](
const InstPartition *
P) {
return !P->hasDepCycle(); });
320 void mergeNonIfConvertible() {
321 mergeAdjacentPartitionsIf([&](
const InstPartition *Partition) {
322 if (Partition->hasDepCycle())
326 bool seenStore =
false;
328 for (
auto *Inst : *Partition)
329 if (isa<StoreInst>(Inst)) {
339 void mergeBeforePopulating() {
340 mergeAdjacentNonCyclic();
342 mergeNonIfConvertible();
352 bool mergeToAvoidDuplicatedLoads() {
356 LoadToPartitionT LoadToPartition;
357 ToBeMergedT ToBeMerged;
362 for (PartitionContainerT::iterator I = PartitionContainer.begin(),
363 E = PartitionContainer.end();
370 if (isa<LoadInst>(Inst)) {
372 LoadToPartitionT::iterator LoadToPart;
374 std::tie(LoadToPart, NewElt) =
375 LoadToPartition.insert(std::make_pair(Inst, PartI));
378 <<
"Merging partitions due to this load in multiple " 379 <<
"partitions: " << PartI <<
", " << LoadToPart->second
386 ToBeMerged.unionSets(PartI, &*PartJ);
387 }
while (&*PartJ != LoadToPart->second);
391 if (ToBeMerged.empty())
396 for (ToBeMergedT::iterator I = ToBeMerged.begin(),
E = ToBeMerged.end();
401 auto PartI = I->getData();
402 for (
auto PartJ :
make_range(std::next(ToBeMerged.member_begin(I)),
403 ToBeMerged.member_end())) {
404 PartJ->moveTo(*PartI);
409 PartitionContainer.remove_if(
410 [](
const InstPartition &P) {
return P.empty(); });
417 void setupPartitionIdOnInstructions() {
419 for (
const auto &Partition : PartitionContainer) {
422 InstToPartitionIdT::iterator Iter;
424 std::tie(Iter, NewElt) =
425 InstToPartitionId.insert(std::make_pair(Inst, PartitionID));
435 void populateUsedSet() {
436 for (
auto &P : PartitionContainer)
447 assert(Pred &&
"Preheader does not have a single predecessor");
449 assert(ExitBlock &&
"No single exit block");
452 assert(!PartitionContainer.empty() &&
"at least two partitions expected");
456 "preheader not empty");
465 unsigned Index = getSize() - 1;
466 for (
auto I = std::next(PartitionContainer.rbegin()),
467 E = PartitionContainer.rend();
471 NewLoop = Part->cloneLoopWithPreheader(TopPH, Pred, Index, LI, DT);
473 Part->getVMap()[ExitBlock] = TopPH;
474 Part->remapInstructions();
475 setNewLoopID(OrigLoopID, Part);
480 setNewLoopID(OrigLoopID, &PartitionContainer.back());
485 for (
auto Curr = PartitionContainer.cbegin(),
486 Next = std::next(PartitionContainer.cbegin()),
487 E = PartitionContainer.cend();
488 Next !=
E; ++Curr, ++Next)
490 Next->getDistributedLoop()->getLoopPreheader(),
491 Curr->getDistributedLoop()->getExitingBlock());
495 void removeUnusedInsts() {
496 for (
auto &Partition : PartitionContainer)
497 Partition.removeUnusedInsts();
510 unsigned N = RtPtrCheck->
Pointers.size();
512 for (
unsigned I = 0; I <
N; ++
I) {
517 int &Partition = PtrToPartitions[
I];
523 int ThisPartition = this->InstToPartitionId[Inst];
525 Partition = ThisPartition;
527 else if (Partition == -1)
529 else if (Partition != (
int)ThisPartition)
532 assert(Partition != -2 &&
"Pointer not belonging to any partition");
535 return PtrToPartitions;
540 for (
const auto &P : PartitionContainer) {
541 OS <<
"Partition " << Index++ <<
" (" << &P <<
"):\n";
550 const InstPartitionContainer &Partitions) {
551 Partitions.print(OS);
556 void printBlocks()
const {
558 for (
const auto &P : PartitionContainer) {
559 dbgs() <<
"\nPartition " << Index++ <<
" (" << &P <<
"):\n";
565 using PartitionContainerT = std::list<InstPartition>;
568 PartitionContainerT PartitionContainer;
572 InstToPartitionIdT InstToPartitionId;
580 template <
class UnaryPredicate>
581 void mergeAdjacentPartitionsIf(UnaryPredicate
Predicate) {
582 InstPartition *PrevMatch =
nullptr;
583 for (
auto I = PartitionContainer.begin(); I != PartitionContainer.end();) {
585 if (PrevMatch ==
nullptr && DoesMatch) {
588 }
else if (PrevMatch !=
nullptr && DoesMatch) {
589 I->moveTo(*PrevMatch);
590 I = PartitionContainer.erase(I);
599 void setNewLoopID(
MDNode *OrigLoopID, InstPartition *Part) {
604 : LLVMLoopDistributeFollowupCoincident});
606 Loop *NewLoop = Part->getDistributedLoop();
618 class MemoryInstructionDependences {
624 unsigned NumUnsafeDependencesStartOrEnd = 0;
631 AccessesType::const_iterator
begin()
const {
return Accesses.
begin(); }
632 AccessesType::const_iterator
end()
const {
return Accesses.
end(); }
634 MemoryInstructionDependences(
637 Accesses.append(Instructions.
begin(), Instructions.
end());
640 for (
auto &Dep : Dependences)
641 if (Dep.isPossiblyBackward()) {
645 ++Accesses[Dep.Source].NumUnsafeDependencesStartOrEnd;
646 --Accesses[Dep.Destination].NumUnsafeDependencesStartOrEnd;
653 AccessesType Accesses;
657 class LoopDistributeForLoop {
661 : L(L), F(F), LI(LI), DT(DT), SE(SE), ORE(ORE) {
671 <<
"\" checking " << *L <<
"\n");
674 return fail(
"MultipleExitBlocks",
"multiple exit blocks");
676 return fail(
"NotLoopSimplifyForm",
677 "loop is not in loop-simplify form");
687 return fail(
"MemOpsCanBeVectorized",
688 "memory operations are safe for vectorization");
691 if (!Dependences || Dependences->empty())
692 return fail(
"NoUnsafeDeps",
"no unsafe dependences to isolate");
694 InstPartitionContainer Partitions(L, LI, DT);
719 int NumUnsafeDependencesActive = 0;
720 for (
auto &InstDep : MID) {
724 if (NumUnsafeDependencesActive ||
725 InstDep.NumUnsafeDependencesStartOrEnd > 0)
726 Partitions.addToCyclicPartition(I);
728 Partitions.addToNewNonCyclicPartition(I);
729 NumUnsafeDependencesActive += InstDep.NumUnsafeDependencesStartOrEnd;
730 assert(NumUnsafeDependencesActive >= 0 &&
731 "Negative number of dependences active");
740 for (
auto *Inst : DefsUsedOutside)
741 Partitions.addToNewNonCyclicPartition(Inst);
744 if (Partitions.getSize() < 2)
745 return fail(
"CantIsolateUnsafeDeps",
746 "cannot isolate unsafe dependencies");
750 Partitions.mergeBeforePopulating();
752 if (Partitions.getSize() < 2)
753 return fail(
"CantIsolateUnsafeDeps",
754 "cannot isolate unsafe dependencies");
757 Partitions.populateUsedSet();
762 if (Partitions.mergeToAvoidDuplicatedLoads()) {
763 LLVM_DEBUG(
dbgs() <<
"\nPartitions merged to ensure unique loads:\n" 765 if (Partitions.getSize() < 2)
766 return fail(
"CantIsolateUnsafeDeps",
767 "cannot isolate unsafe dependencies");
775 return fail(
"TooManySCEVRuntimeChecks",
776 "too many SCEV run-time checks needed.\n");
779 return fail(
"HeuristicDisabled",
"distribution heuristic disabled");
784 Partitions.setupPartitionIdOnInstructions();
793 auto PtrToPartition = Partitions.computePartitionSetForPointers(*LAI);
795 const auto &AllChecks = RtPtrChecking->
getChecks();
796 auto Checks = includeOnlyCrossPartitionChecks(AllChecks, PtrToPartition,
805 LVer.setAliasChecks(std::move(Checks));
807 LVer.versionLoop(DefsUsedOutside);
808 LVer.annotateLoopWithNoAlias();
813 MDNode *UnversionedLoopID =
816 LLVMLoopDistributeFollowupFallback},
817 "llvm.loop.distribute.",
true)
819 LVer.getNonVersionedLoop()->setLoopID(UnversionedLoopID);
824 Partitions.cloneLoops();
828 Partitions.removeUnusedInsts();
837 ++NumLoopsDistributed;
842 <<
"distributed loop";
850 bool Forced = isForced().getValueOr(
false);
858 <<
"loop not distributed: use -Rpass-analysis=loop-distribute for " 868 <<
"loop not distributed: " << Message);
875 "explicitly specified loop distribution"));
894 includeOnlyCrossPartitionChecks(
900 copy_if(AllChecks, std::back_inserter(Checks),
902 for (
unsigned PtrIdx1 : Check.first->Members)
903 for (
unsigned PtrIdx2 : Check.second->Members)
919 PtrToPartition, PtrIdx1, PtrIdx2))
936 assert(Op && mdconst::hasa<ConstantInt>(*Op) &&
"invalid metadata");
937 IsForced = mdconst::extract<ConstantInt>(*Op)->getZExtValue();
970 for (
Loop *TopLevelLoop : *LI)
977 bool Changed =
false;
978 for (
Loop *L : Worklist) {
979 LoopDistributeForLoop
LDL(L, &F, LI, DT, SE, ORE);
984 Changed |= LDL.processLoop(GetLAA);
1004 if (skipFunction(F))
1007 auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1008 auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
1009 auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1010 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1011 auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
1012 std::function<const LoopAccessInfo &(Loop &)> GetLAA =
1015 return runImpl(F, LI, DT, SE, ORE, GetLAA);
1047 std::function<const LoopAccessInfo &(Loop &)> GetLAA =
1053 bool Changed =
runImpl(F, &LI, &DT, &SE, &ORE, GetLAA);
Legacy wrapper pass to provide the GlobalsAAResult object.
static bool Check(DecodeStatus &Out, DecodeStatus In)
const_iterator end(StringRef path)
Get end iterator over path.
void printChecks(raw_ostream &OS, const SmallVectorImpl< PointerCheck > &Checks, unsigned Depth=0) const
Print Checks.
Tracking metadata reference owned by Metadata.
const MemoryDepChecker & getDepChecker() const
the Memory Dependence Checker which can determine the loop-independent and loop-carried dependences b...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
This is the interface for a simple mod/ref and alias analysis over globals.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly...
static cl::opt< unsigned > PragmaDistributeSCEVCheckThreshold("loop-distribute-scev-check-threshold-with-pragma", cl::init(128), cl::Hidden, cl::desc("The maximum number of SCEV checks allowed for Loop " "Distribution for loop marked with #pragma loop distribute(enable)"))
void push_back(const T &Elt)
const RuntimePointerChecking * getRuntimePointerChecking() const
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
The main scalar evolution driver.
static cl::opt< bool > LDistVerify("loop-distribute-verify", cl::Hidden, cl::desc("Turn on DominatorTree and LoopInfo verification " "after Loop Distribution"), cl::init(false))
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
Analysis pass providing the TargetTransformInfo.
STATISTIC(NumFunctions, "Total number of functions")
SmallVector< Instruction *, 4 > getInstructionsForAccess(Value *Ptr, bool isWrite) const
Return the list of instructions that use Ptr to read or write memory.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
Analysis pass which computes a DominatorTree.
Checks memory dependences among accesses to the same underlying object to determine whether there vec...
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...
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
iterator begin()
Instruction iterator methods.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
static const char *const LLVMLoopDistributeFollowupSequential
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Diagnostic information for optimization failures.
static bool arePointersInSamePartition(const SmallVectorImpl< int > &PtrToPartition, unsigned PtrIdx1, unsigned PtrIdx2)
Check if pointers are in the same partition.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
friend const_iterator begin(StringRef path, Style style)
Get begin iterator over path.
Analysis pass that exposes the LoopInfo for a function.
SmallVector< Instruction *, 8 > findDefsUsedOutsideOfLoop(Loop *L)
Returns the instructions that use values defined in the loop.
BlockT * getHeader() const
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
const SmallVectorImpl< Instruction * > & getMemoryInstructions() const
The vector of memory access instructions.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
static const char *const LLVMLoopDistributeFollowupCoincident
static const char *const LLVMLoopDistributeFollowupFallback
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
const T & getValue() const LLVM_LVALUE_FUNCTION
static cl::opt< bool > DistributeNonIfConvertible("loop-distribute-non-if-convertible", cl::Hidden, cl::desc("Whether to distribute into a loop that may not be " "if-convertible by the loop vectorizer"), cl::init(false))
This header provides classes for managing per-loop analyses.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT, ScalarEvolution *SE, OptimizationRemarkEmitter *ORE, std::function< const LoopAccessInfo &(Loop &)> &GetLAA)
Shared implementation between new and old PMs.
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
friend const_iterator end(StringRef path)
Get end iterator over path.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
bool needsChecking(const CheckingPtrGroup &M, const CheckingPtrGroup &N) const
Decide if we need to add a check between two groups of pointers, according to needsChecking.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM Basic Block Representation.
This is an important class for using LLVM in a threaded context.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This analysis provides dependence information for the memory accesses of a loop.
INITIALIZE_PASS_BEGIN(LoopDistributeLegacy, LDIST_NAME, ldist_name, false, false) FunctionPass *llvm
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
A manager for alias analyses.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
Represent the analysis usage information of a pass.
Analysis pass providing a never-invalidated alias analysis result.
FunctionPass class - This class is used to implement most global optimizations.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
const PredicatedScalarEvolution & getPSE() const
Used to add runtime SCEV checks.
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
std::pair< const CheckingPtrGroup *, const CheckingPtrGroup * > PointerCheck
A memcheck which made up of a pair of grouped pointers.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
static cl::opt< unsigned > DistributeSCEVCheckThreshold("loop-distribute-scev-check-threshold", cl::init(8), cl::Hidden, cl::desc("The maximum number of SCEV checks allowed for Loop " "Distribution"))
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
A function analysis which provides an AssumptionCache.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
const SmallVectorImpl< Dependence > * getDependences() const
Returns the memory dependences.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool isAlwaysTrue() const override
Implementation of the SCEVPredicate interface.
const SCEVUnionPredicate & getUnionPredicate() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
void initializeLoopDistributeLegacyPass(PassRegistry &)
Drive the analysis of memory accesses in the loop.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Optional< MDNode * > makeFollowupLoopID(MDNode *OrigLoopID, ArrayRef< StringRef > FollowupAttrs, const char *InheritOptionsAttrsPrefix="", bool AlwaysNew=false)
Create a new loop identifier for a loop created from a loop transformation.
static const char *const LLVMLoopDistributeFollowupAll
static const char ldist_name[]
Holds information about the memory runtime legality checks to verify that a group of pointers do not ...
Analysis pass that exposes the ScalarEvolution for a function.
unsigned getComplexity() const override
We estimate the complexity of a union predicate as the size number of predicates in the union...
bool isLoopSimplifyForm() const
Return true if the Loop is in the form that the LoopSimplify form transforms loops to...
MDNode * getLoopID() const
Return the llvm.loop loop id metadata node for this loop if it is present.
This analysis provides dependence information for the memory accesses of a loop.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Dependece between memory access instructions.
Represents a single loop in the control flow graph.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
Optional< const MDOperand * > findStringMetadataForLoop(const Loop *TheLoop, StringRef Name)
Find string metadata for loop.
SmallVector< PointerInfo, 2 > Pointers
Information about the pointers that may require checking.
iterator_range< value_op_iterator > operand_values()
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Analysis pass providing the TargetLibraryInfo.
iterator_range< df_iterator< T > > depth_first(const T &G)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents a composition of other SCEV predicates, and is the class that most clients will...
static cl::opt< bool > EnableLoopDistribute("enable-loop-distribute", cl::Hidden, cl::desc("Enable the new, experimental LoopDistribution Pass"), cl::init(false))
LLVM Value Representation.
static bool blockNeedsPredication(BasicBlock *BB, Loop *TheLoop, DominatorTree *DT)
Return true if the block BB needs to be predicated in order for the loop to be vectorized.
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Split the specified block at the specified instruction - everything before SplitPt stays in Old and e...
Loop * cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, Loop *OrigLoop, ValueToValueMapTy &VMap, const Twine &NameSuffix, LoopInfo *LI, DominatorTree *DT, SmallVectorImpl< BasicBlock *> &Blocks)
Clones a loop OrigLoop.
This class implements an extremely fast bulk output stream that can only output to a stream...
The legacy pass manager's analysis pass to compute loop information.
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
This header defines various interfaces for pass management in LLVM.
bool hasDisableAllTransformsHint(const Loop *L)
Look for the loop attribute that disables all transformation heuristic.
const SmallVector< PointerCheck, 4 > & getChecks() const
Returns the checks that generateChecks created.
Dependence - This class represents a dependence between two memory memory references in a function...
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
bool canVectorizeMemory() const
Return true we can analyze the memory accesses in the loop and there are no memory dependence cycles...
static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg)
FunctionPass * createLoopDistributePass()
const BasicBlock * getParent() const
void remapInstructionsInBlocks(const SmallVectorImpl< BasicBlock *> &Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...