71#define LDIST_NAME "loop-distribute"
72#define DEBUG_TYPE LDIST_NAME
77 "llvm.loop.distribute.followup_all";
79 "llvm.loop.distribute.followup_coincident";
81 "llvm.loop.distribute.followup_sequential";
83 "llvm.loop.distribute.followup_fallback";
88 cl::desc(
"Turn on DominatorTree and LoopInfo verification "
89 "after Loop Distribution"),
93 "loop-distribute-non-if-convertible",
cl::Hidden,
94 cl::desc(
"Whether to distribute into a loop that may not be "
95 "if-convertible by the loop vectorizer"),
100 cl::desc(
"The maximum number of SCEV checks allowed for Loop "
104 "loop-distribute-scev-check-threshold-with-pragma",
cl::init(128),
106 cl::desc(
"The maximum number of SCEV checks allowed for Loop "
107 "Distribution for loop marked with #pragma clang loop "
108 "distribute(enable)"));
112 cl::desc(
"Enable the new, experimental LoopDistribution Pass"),
115STATISTIC(NumLoopsDistributed,
"Number of loops distributed");
126 : DepCycle(DepCycle), OrigLoop(L) {
131 bool hasDepCycle()
const {
return DepCycle; }
141 bool empty()
const {
return Set.empty(); }
145 void moveTo(InstPartition &
Other) {
148 Other.DepCycle |= DepCycle;
153 void populateUsedSet() {
157 for (
auto *
B : OrigLoop->getBlocks())
158 Set.insert(
B->getTerminator());
163 while (!Worklist.empty()) {
166 for (
Value *V :
I->operand_values()) {
167 auto *
I = dyn_cast<Instruction>(V);
168 if (
I && OrigLoop->contains(
I->getParent()) &&
Set.insert(
I))
169 Worklist.push_back(
I);
183 LI, DT, ClonedLoopBlocks);
189 const Loop *getClonedLoop()
const {
return ClonedLoop; }
194 Loop *getDistributedLoop()
const {
195 return ClonedLoop ? ClonedLoop : OrigLoop;
203 void remapInstructions() {
209 void removeUnusedInsts() {
212 for (
auto *
Block : OrigLoop->getBlocks())
213 for (
auto &Inst : *
Block)
214 if (!
Set.count(&Inst)) {
217 NewInst = cast<Instruction>(VMap[NewInst]);
219 assert(!isa<BranchInst>(NewInst) &&
220 "Branches are marked used early on");
221 Unused.push_back(NewInst);
226 for (
auto *Inst :
reverse(Unused)) {
227 if (!Inst->use_empty())
229 Inst->eraseFromParent();
234 OS << (DepCycle ?
" (cycle)\n" :
"\n");
237 OS <<
" " <<
I->getParent()->getName() <<
":" << *
I <<
"\n";
241 for (
auto *BB : getDistributedLoop()->getBlocks())
257 Loop *ClonedLoop =
nullptr;
271class InstPartitionContainer {
276 :
L(
L), LI(LI), DT(DT) {}
279 unsigned getSize()
const {
return PartitionContainer.size(); }
285 if (PartitionContainer.empty() || !PartitionContainer.back().hasDepCycle())
286 PartitionContainer.emplace_back(Inst, L,
true);
288 PartitionContainer.back().add(Inst);
296 void addToNewNonCyclicPartition(
Instruction *Inst) {
297 PartitionContainer.emplace_back(Inst, L);
305 void mergeAdjacentNonCyclic() {
306 mergeAdjacentPartitionsIf(
307 [](
const InstPartition *
P) {
return !
P->hasDepCycle(); });
312 void mergeNonIfConvertible() {
313 mergeAdjacentPartitionsIf([&](
const InstPartition *Partition) {
314 if (Partition->hasDepCycle())
318 bool seenStore =
false;
320 for (
auto *Inst : *Partition)
321 if (isa<StoreInst>(Inst)) {
331 void mergeBeforePopulating() {
332 mergeAdjacentNonCyclic();
334 mergeNonIfConvertible();
344 bool mergeToAvoidDuplicatedLoads() {
348 LoadToPartitionT LoadToPartition;
349 ToBeMergedT ToBeMerged;
354 for (PartitionContainerT::iterator
I = PartitionContainer.begin(),
355 E = PartitionContainer.end();
362 if (isa<LoadInst>(Inst)) {
364 LoadToPartitionT::iterator LoadToPart;
366 std::tie(LoadToPart, NewElt) =
367 LoadToPartition.insert(std::make_pair(Inst, PartI));
371 <<
"LDist: Merging partitions due to this load in multiple "
372 <<
"partitions: " << PartI <<
", " << LoadToPart->second <<
"\n"
378 ToBeMerged.unionSets(PartI, &*PartJ);
379 }
while (&*PartJ != LoadToPart->second);
383 if (ToBeMerged.empty())
388 for (ToBeMergedT::iterator
I = ToBeMerged.begin(), E = ToBeMerged.end();
393 auto PartI =
I->getData();
394 for (
auto *PartJ :
make_range(std::next(ToBeMerged.member_begin(
I)),
395 ToBeMerged.member_end())) {
396 PartJ->moveTo(*PartI);
401 PartitionContainer.remove_if(
402 [](
const InstPartition &
P) {
return P.empty(); });
409 void setupPartitionIdOnInstructions() {
411 for (
const auto &Partition : PartitionContainer) {
416 std::tie(Iter, NewElt) =
417 InstToPartitionId.insert(std::make_pair(Inst, PartitionID));
427 void populateUsedSet() {
428 for (
auto &
P : PartitionContainer)
439 assert(Pred &&
"Preheader does not have a single predecessor");
441 assert(ExitBlock &&
"No single exit block");
444 assert(!PartitionContainer.empty() &&
"at least two partitions expected");
448 "preheader not empty");
451 MDNode *OrigLoopID =
L->getLoopID();
459 NewLoop = Part.cloneLoopWithPreheader(TopPH, Pred, Index, LI, DT);
461 Part.getVMap()[ExitBlock] = TopPH;
462 Part.remapInstructions();
463 setNewLoopID(OrigLoopID, &Part);
470 setNewLoopID(OrigLoopID, &PartitionContainer.back());
475 for (
auto Curr = PartitionContainer.cbegin(),
476 Next = std::next(PartitionContainer.cbegin()),
477 E = PartitionContainer.cend();
478 Next != E; ++Curr, ++Next)
480 Next->getDistributedLoop()->getLoopPreheader(),
481 Curr->getDistributedLoop()->getExitingBlock());
485 void removeUnusedInsts() {
486 for (
auto &Partition : PartitionContainer)
487 Partition.removeUnusedInsts();
500 unsigned N = RtPtrCheck->
Pointers.size();
502 for (
unsigned I = 0;
I <
N; ++
I) {
507 int &Partition = PtrToPartitions[
I];
513 int ThisPartition = this->InstToPartitionId[Inst];
515 Partition = ThisPartition;
517 else if (Partition == -1)
519 else if (Partition != (
int)ThisPartition)
522 assert(Partition != -2 &&
"Pointer not belonging to any partition");
525 return PtrToPartitions;
530 for (
const auto &
P : PartitionContainer) {
531 OS <<
"LDist: Partition " <<
Index++ <<
":";
540 const InstPartitionContainer &Partitions) {
541 Partitions.print(
OS);
548 for (
const auto &
P : PartitionContainer) {
549 OS <<
"LDist: Partition " <<
Index++ <<
":";
555 using PartitionContainerT = std::list<InstPartition>;
558 PartitionContainerT PartitionContainer;
562 InstToPartitionIdT InstToPartitionId;
570 template <
class UnaryPredicate>
571 void mergeAdjacentPartitionsIf(UnaryPredicate Predicate) {
572 InstPartition *PrevMatch =
nullptr;
573 for (
auto I = PartitionContainer.begin();
I != PartitionContainer.end();) {
575 if (PrevMatch ==
nullptr && DoesMatch) {
578 }
else if (PrevMatch !=
nullptr && DoesMatch) {
579 I->moveTo(*PrevMatch);
580 I = PartitionContainer.erase(
I);
589 void setNewLoopID(
MDNode *OrigLoopID, InstPartition *Part) {
596 Loop *NewLoop = Part->getDistributedLoop();
608class MemoryInstructionDependences {
614 unsigned NumUnsafeDependencesStartOrEnd = 0;
624 MemoryInstructionDependences(
630 for (
const auto &Dep : Dependences)
631 if (Dep.isPossiblyBackward()) {
635 ++Accesses[Dep.Source].NumUnsafeDependencesStartOrEnd;
636 --Accesses[Dep.Destination].NumUnsafeDependencesStartOrEnd;
643 AccessesType Accesses;
647class LoopDistributeForLoop {
652 :
L(
L),
F(
F), LI(LI), DT(DT), SE(SE), LAIs(LAIs), ORE(ORE) {
658 assert(
L->isInnermost() &&
"Only process inner loops.");
661 <<
L->getHeader()->getParent()->getName() <<
"' from "
662 <<
L->getLocStr() <<
"\n");
665 if (!
L->getExitBlock())
666 return fail(
"MultipleExitBlocks",
"multiple exit blocks");
667 if (!
L->isLoopSimplifyForm())
668 return fail(
"NotLoopSimplifyForm",
669 "loop is not in loop-simplify form");
670 if (!
L->isRotatedForm())
671 return fail(
"NotBottomTested",
"loop is not bottom tested");
675 LAI = &LAIs.getInfo(*L);
680 return fail(
"MemOpsCanBeVectorized",
681 "memory operations are safe for vectorization");
684 if (!Dependences || Dependences->empty())
685 return fail(
"NoUnsafeDeps",
"no unsafe dependences to isolate");
688 <<
L->getHeader()->getName() <<
"\n");
690 InstPartitionContainer Partitions(L, LI, DT);
715 int NumUnsafeDependencesActive = 0;
716 for (
const auto &InstDep : MID) {
720 if (NumUnsafeDependencesActive ||
721 InstDep.NumUnsafeDependencesStartOrEnd > 0)
722 Partitions.addToCyclicPartition(
I);
724 Partitions.addToNewNonCyclicPartition(
I);
725 NumUnsafeDependencesActive += InstDep.NumUnsafeDependencesStartOrEnd;
726 assert(NumUnsafeDependencesActive >= 0 &&
727 "Negative number of dependences active");
736 for (
auto *Inst : DefsUsedOutside)
737 Partitions.addToNewNonCyclicPartition(Inst);
739 LLVM_DEBUG(
dbgs() <<
"LDist: Seeded partitions:\n" << Partitions);
740 if (Partitions.getSize() < 2)
741 return fail(
"CantIsolateUnsafeDeps",
742 "cannot isolate unsafe dependencies");
746 Partitions.mergeBeforePopulating();
747 LLVM_DEBUG(
dbgs() <<
"LDist: Merged partitions:\n" << Partitions);
748 if (Partitions.getSize() < 2)
749 return fail(
"CantIsolateUnsafeDeps",
750 "cannot isolate unsafe dependencies");
753 Partitions.populateUsedSet();
754 LLVM_DEBUG(
dbgs() <<
"LDist: Populated partitions:\n" << Partitions);
758 if (Partitions.mergeToAvoidDuplicatedLoads()) {
759 LLVM_DEBUG(
dbgs() <<
"LDist: Partitions merged to ensure unique loads:\n"
761 if (Partitions.getSize() < 2)
762 return fail(
"CantIsolateUnsafeDeps",
763 "cannot isolate unsafe dependencies");
770 return fail(
"RuntimeCheckWithConvergent",
771 "may not insert runtime check with convergent operation");
777 return fail(
"TooManySCEVRuntimeChecks",
778 "too many SCEV run-time checks needed.\n");
781 return fail(
"HeuristicDisabled",
"distribution heuristic disabled");
784 <<
L->getHeader()->getName() <<
"\n");
787 Partitions.setupPartitionIdOnInstructions();
790 auto PtrToPartition = Partitions.computePartitionSetForPointers(*LAI);
792 const auto &AllChecks = RtPtrChecking->
getChecks();
793 auto Checks = includeOnlyCrossPartitionChecks(AllChecks, PtrToPartition,
797 return fail(
"RuntimeCheckWithConvergent",
798 "may not insert runtime check with convergent operation");
810 MDNode *OrigLoopID =
L->getLoopID();
815 LVer.versionLoop(DefsUsedOutside);
816 LVer.annotateLoopWithNoAlias();
824 "llvm.loop.distribute.",
true);
825 LVer.getNonVersionedLoop()->setLoopID(UnversionedLoopID);
830 Partitions.cloneLoops();
834 Partitions.removeUnusedInsts();
840 assert(DT->
verify(DominatorTree::VerificationLevel::Fast));
843 ++NumLoopsDistributed;
848 <<
"distributed loop";
856 bool Forced = isForced().value_or(
false);
863 L->getStartLoc(),
L->getHeader())
864 <<
"loop not distributed: use -Rpass-analysis=loop-distribute for "
873 RemarkName,
L->getStartLoc(),
L->getHeader())
874 <<
"loop not distributed: " << Message);
880 *F,
L->getStartLoc(),
"loop not distributed: failed "
881 "explicitly specified loop distribution"));
891 const std::optional<bool> &isForced()
const {
return IsForced; }
905 copy_if(AllChecks, std::back_inserter(Checks),
907 for (
unsigned PtrIdx1 :
Check.first->Members)
908 for (
unsigned PtrIdx2 :
Check.second->Members)
924 PtrToPartition, PtrIdx1, PtrIdx2))
935 std::optional<const MDOperand *>
Value =
941 assert(
Op && mdconst::hasa<ConstantInt>(*
Op) &&
"invalid metadata");
942 IsForced = mdconst::extract<ConstantInt>(*Op)->getZExtValue();
962 std::optional<bool> IsForced;
975 for (
Loop *TopLevelLoop : *LI)
978 if (L->isInnermost())
982 bool Changed =
false;
983 for (
Loop *L : Worklist) {
984 LoopDistributeForLoop LDL(L, &
F, LI, DT, SE, LAIs, ORE);
989 Changed |= LDL.processLoop();
1004 bool Changed =
runImpl(
F, &LI, &DT, &SE, &ORE, LAIs);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, SDValue Val={})
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
std::optional< std::vector< StOtherPiece > > Other
Generic implementation of equivalence classes through the use Tarjan's efficient union-find algorithm...
static bool runImpl(Function &F, const TargetLowering &TLI)
This is the interface for a simple mod/ref and alias analysis over globals.
This header defines various interfaces for pass management in LLVM.
This header provides classes for managing per-loop analyses.
static const char *const LLVMLoopDistributeFollowupCoincident
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))
static cl::opt< bool > EnableLoopDistribute("enable-loop-distribute", cl::Hidden, cl::desc("Enable the new, experimental LoopDistribution Pass"), cl::init(false))
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"))
static const char *const LLVMLoopDistributeFollowupSequential
static const char *const LLVMLoopDistributeFollowupAll
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 clang loop " "distribute(enable)"))
static const char *const LLVMLoopDistributeFollowupFallback
static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT, ScalarEvolution *SE, OptimizationRemarkEmitter *ORE, LoopAccessInfoManager &LAIs)
static cl::opt< bool > LDistVerify("loop-distribute-verify", cl::Hidden, cl::desc("Turn on DominatorTree and LoopInfo verification " "after Loop Distribution"), cl::init(false))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
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)
static unsigned getSize(unsigned Kind)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
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...
This class represents an Operation in the Expression.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Dependence - This class represents a dependence between two memory memory references in a function.
Diagnostic information for optimization failures.
Analysis pass which computes a DominatorTree.
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...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
This is an important class for using LLVM in a threaded context.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
This analysis provides dependence information for the memory accesses of a loop.
Drive the analysis of memory accesses in the loop.
const MemoryDepChecker & getDepChecker() const
the Memory Dependence Checker which can determine the loop-independent and loop-carried dependences b...
const RuntimePointerChecking * getRuntimePointerChecking() const
bool canVectorizeMemory() const
Return true we can analyze the memory accesses in the loop and there are no memory dependence cycles.
const PredicatedScalarEvolution & getPSE() const
Used to add runtime SCEV checks.
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.
SmallVector< Instruction *, 4 > getInstructionsForAccess(Value *Ptr, bool isWrite) const
Return the list of instructions that use Ptr to read or write memory.
bool hasConvergentOp() const
Return true if there is a convergent operation in the loop.
Analysis pass that exposes the LoopInfo for a function.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
Tracking metadata reference owned by Metadata.
Checks memory dependences among accesses to the same underlying object to determine whether there vec...
const SmallVectorImpl< Instruction * > & getMemoryInstructions() const
The vector of memory access instructions.
const SmallVectorImpl< Dependence > * getDependences() const
Returns the memory dependences.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
const SCEVPredicate & getPredicate() const
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
Holds information about the memory runtime legality checks to verify that a group of pointers do not ...
void printChecks(raw_ostream &OS, const SmallVectorImpl< RuntimePointerCheck > &Checks, unsigned Depth=0) const
Print Checks.
bool needsChecking(const RuntimeCheckingPtrGroup &M, const RuntimeCheckingPtrGroup &N) const
Decide if we need to add a check between two groups of pointers, according to needsChecking.
static bool arePointersInSamePartition(const SmallVectorImpl< int > &PtrToPartition, unsigned PtrIdx1, unsigned PtrIdx2)
Check if pointers are in the same partition.
SmallVector< PointerInfo, 2 > Pointers
Information about the pointers that may require checking.
const SmallVectorImpl< RuntimePointerCheck > & getChecks() const
Returns the checks that generateChecks created.
This class represents an assumption made using SCEV expressions which can be checked at run-time.
virtual unsigned getComplexity() const
Returns the estimated complexity of this predicate.
virtual bool isAlwaysTrue() const =0
Returns true if the predicate is always true.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
typename vector_type::const_iterator iterator
typename vector_type::const_iterator const_iterator
A SetVector that performs no allocations if smaller than a certain size.
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.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
LLVM Value Representation.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
friend const_iterator begin(StringRef path, Style style)
Get begin iterator over path.
friend const_iterator end(StringRef path)
Get end iterator over path.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
initializer< Ty > init(const Ty &Val)
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
std::pair< const RuntimeCheckingPtrGroup *, const RuntimeCheckingPtrGroup * > RuntimePointerCheck
A memcheck which made up of a pair of grouped pointers.
std::optional< const MDOperand * > findStringMetadataForLoop(const Loop *TheLoop, StringRef Name)
Find string metadata for loop.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::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.
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.
SmallVector< Instruction *, 8 > findDefsUsedOutsideOfLoop(Loop *L)
Returns the instructions that use values defined in the loop.
auto reverse(ContainerTy &&C)
Loop * cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB, Loop *OrigLoop, ValueToValueMapTy &VMap, const Twine &NameSuffix, LoopInfo *LI, DominatorTree *DT, SmallVectorImpl< BasicBlock * > &Blocks)
Clones a loop OrigLoop.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool hasDisableAllTransformsHint(const Loop *L)
Look for the loop attribute that disables all transformation heuristic.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
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.
iterator_range< df_iterator< T > > depth_first(const T &G)
Dependece between memory access instructions.