85 #define DEBUG_TYPE "gvn-hoist" 87 STATISTIC(NumHoisted,
"Number of instructions hoisted");
88 STATISTIC(NumRemoved,
"Number of instructions removed");
89 STATISTIC(NumLoadsHoisted,
"Number of loads hoisted");
90 STATISTIC(NumLoadsRemoved,
"Number of loads removed");
91 STATISTIC(NumStoresHoisted,
"Number of stores hoisted");
92 STATISTIC(NumStoresRemoved,
"Number of stores removed");
93 STATISTIC(NumCallsHoisted,
"Number of calls hoisted");
94 STATISTIC(NumCallsRemoved,
"Number of calls removed");
98 cl::desc(
"Max number of instructions to hoist " 99 "(default unlimited = -1)"));
103 cl::desc(
"Max number of basic blocks on the path between " 104 "hoisting locations (default = 4, unlimited = -1)"));
108 cl::desc(
"Hoist instructions from the beginning of the BB up to the " 109 "maximum specified depth (default = 100, unlimited = -1)"));
113 cl::desc(
"Maximum length of dependent chains to hoist " 114 "(default = 10, unlimited = -1)"));
129 using VNType = std::pair<unsigned, unsigned>;
175 VNtoScalars[{V,
InvalidVN}].push_back(I);
190 VNtoLoads[{V,
InvalidVN}].push_back(Load);
229 auto Entry = std::make_pair(V,
InvalidVN);
232 VNtoCallsScalars[Entry].push_back(Call);
234 VNtoCallsLoads[Entry].push_back(Call);
236 VNtoCallsStores[Entry].push_back(Call);
245 static const unsigned KnownIDs[] = {
260 : DT(DT), PDT(PDT), AA(AA), MD(MD), MSSA(MSSA),
266 VN.setAliasAnalysis(AA);
272 DFSNumber[BB] = ++BBI;
274 for (
auto &Inst : *BB)
275 DFSNumber[&Inst] = ++
I;
285 auto HoistStat = hoistExpressions(F);
286 if (HoistStat.first + HoistStat.second == 0)
289 if (HoistStat.second > 0)
311 if (isa<ConstantExpr>(V))
313 if (isa<UndefValue>(V))
315 if (isa<Constant>(V))
317 else if (
auto *A = dyn_cast<Argument>(V))
318 return 3 + A->getArgNo();
322 auto Result = DFSNumber.lookup(V);
324 return 4 + NumFuncArgs + Result;
336 std::unique_ptr<MemorySSAUpdater> MSSAUpdater;
341 unsigned NumFuncArgs;
342 const bool HoistingGeps =
false;
348 auto It = BBSideEffects.
find(BB);
349 if (It != BBSideEffects.
end())
353 BBSideEffects[BB] =
true;
358 BBSideEffects[BB] =
true;
362 BBSideEffects[BB] =
false;
378 unsigned I1DFS = DFSNumber.
lookup(I1);
379 unsigned I2DFS = DFSNumber.
lookup(I2);
381 return I1DFS < I2DFS;
394 bool ReachedNewPt =
false;
397 if (
const MemoryUse *MU = dyn_cast<MemoryUse>(&MA)) {
401 if (BB == OldBB && firstInBB(OldPt, Insn))
407 if (firstInBB(Insn, NewPt))
420 int &NBBsOnAllPaths) {
422 if (NBBsOnAllPaths == 0)
432 if ((BB != SrcBB) && HoistBarrier.
count(BB))
446 int &NBBsOnAllPaths) {
451 "def does not dominate new hoisting point");
465 if (hasEHhelper(BB, OldBB, NBBsOnAllPaths))
469 if (hasMemoryUse(NewPt, Def, BB))
473 if (NBBsOnAllPaths != -1)
487 int &NBBsOnAllPaths) {
503 if (hasEHhelper(BB, SrcBB, NBBsOnAllPaths))
507 if (NBBsOnAllPaths != -1)
536 if (
auto *UD = dyn_cast<MemoryUseOrDef>(D))
537 if (!firstInBB(UD->getMemoryInst(), NewPt))
543 if (hasEHOrLoadsOnPath(NewPt, dyn_cast<MemoryDef>(U), NBBsOnAllPaths))
545 }
else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
562 int &NBBsOnAllPaths) {
563 return !hasEHOnPath(HoistBB, BB, NBBsOnAllPaths);
605 if (safeToHoistScalar(BB, Insn->
getParent(), NumBBsOnAllPaths))
609 if (safeToHoistLdSt(BB->
getTerminator(), Insn, UD, K, NumBBsOnAllPaths))
620 auto it1 = ValueBBs.
find(BB);
621 if (it1 != ValueBBs.
end()) {
623 for (std::pair<VNType, Instruction *> &
VI :
reverse(it1->second)) {
626 RenameStack[
VI.first].push_back(
VI.second);
635 auto P = CHIBBs.
find(Pred);
636 if (
P == CHIBBs.
end()) {
639 LLVM_DEBUG(
dbgs() <<
"\nLooking at CHIs in: " << Pred->getName(););
642 auto &VCHI =
P->second;
643 for (
auto It = VCHI.begin(),
E = VCHI.end(); It !=
E;) {
646 auto si = RenameStack.
find(C.
VN);
650 if (si != RenameStack.
end() && si->second.size() &&
653 C.
I = si->second.pop_back_val();
655 <<
"\nCHI Inserted in BB: " << C.
Dest->
getName() << *C.
I 656 <<
", VN: " << C.
VN.first <<
", " << C.
VN.second);
660 [It](
CHIArg &A) {
return A != *It; });
672 auto Root = PDT->
getNode(
nullptr);
683 fillRenameStack(BB, ValueBBs, RenameStack);
686 fillChiArgs(BB, CHIBBs, RenameStack);
694 void findHoistableCandidates(
OutValuesType &CHIBBs, InsKind K,
706 std::stable_sort(CHIs.
begin(), CHIs.
end(), cmpVN);
711 [
B](
CHIArg &A) {
return A != *
B; });
712 auto PrevIt = CHIs.
begin();
713 while (PrevIt != PHIIt) {
720 checkSafety(
make_range(PrevIt, PHIIt), BB, K, Safe);
733 [PrevIt](
CHIArg &A) {
return A != *PrevIt; });
743 std::vector<VNType> Ranks;
744 for (
const auto &Entry : Map) {
745 Ranks.push_back(Entry.first);
752 return (
rank(*Map.lookup(r1).begin()) <
rank(*Map.lookup(r2).begin()));
767 for (
const auto &R : Ranks) {
789 for (
unsigned i = 0; i < V.size(); ++i) {
790 InValue[V[i]->getParent()].push_back(std::make_pair(VN, V[i]));
794 for (
auto IDFB : IDFBlocks) {
795 for (
unsigned i = 0; i < V.size(); ++i) {
799 OutValue[IDFB].push_back(C);
800 LLVM_DEBUG(
dbgs() <<
"\nInsertion a CHI for BB: " << IDFB->getName()
801 <<
", for Insn: " << *V[i]);
809 insertCHI(InValue, OutValue);
811 findHoistableCandidates(OutValue, K, HPL);
821 if (
const auto *Inst = dyn_cast<Instruction>(&
Op))
822 if (!DT->
dominates(Inst->getParent(), HoistPt))
832 if (
const auto *Inst = dyn_cast<Instruction>(&
Op))
833 if (!DT->
dominates(Inst->getParent(), HoistPt)) {
835 dyn_cast<GetElementPtrInst>(Inst)) {
836 if (!allGepOperandsAvailable(GepOp, HoistPt))
852 assert(allGepOperandsAvailable(Gep, HoistPt) &&
853 "GEP operands not available");
865 makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
877 for (
const Instruction *OtherInst : InstructionsToHoist) {
879 if (
auto *OtherLd = dyn_cast<LoadInst>(OtherInst))
880 OtherGep = cast<GetElementPtrInst>(OtherLd->getPointerOperand());
882 OtherGep = cast<GetElementPtrInst>(
892 if (
auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
893 ReplacementLoad->setAlignment(
894 std::min(ReplacementLoad->getAlignment(),
897 }
else if (
auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
898 ReplacementStore->setAlignment(
899 std::min(ReplacementStore->getAlignment(),
902 }
else if (
auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
903 ReplacementAlloca->setAlignment(
904 std::max(ReplacementAlloca->getAlignment(),
906 }
else if (isa<CallInst>(Repl)) {
919 updateAlignment(I, Repl);
924 MSSAUpdater->removeMemoryAccess(OldMA);
942 if (
MemoryPhi *Phi = dyn_cast<MemoryPhi>(U))
946 auto In = Phi->incoming_values();
948 Phi->replaceAllUsesWith(NewMemAcc);
949 MSSAUpdater->removeMemoryAccess(Phi);
958 if (MoveAccess && NewMemAcc) {
965 unsigned NR = rauw(Candidates, Repl, NewMemAcc);
981 if (
auto *Ld = dyn_cast<LoadInst>(Repl)) {
983 }
else if (
auto *St = dyn_cast<StoreInst>(Repl)) {
988 if (isa<GetElementPtrInst>(Val)) {
990 if (!allGepOperandsAvailable(Val, HoistPt))
992 }
else if (!DT->
dominates(Val->getParent(), HoistPt))
998 if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
1001 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
1003 if (Val && isa<GetElementPtrInst>(Val))
1004 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
1010 unsigned NI = 0, NL = 0, NS = 0,
NC = 0, NR = 0;
1022 if (!Repl || firstInBB(I, Repl))
1027 bool MoveAccess =
true;
1030 assert(allOperandsAvailable(Repl, DestBB) &&
1031 "instruction depends on operands that are not available");
1036 Repl = InstructionsToHoist.front();
1041 if (!allOperandsAvailable(Repl, DestBB)) {
1048 if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
1057 DFSNumber[Repl] = DFSNumber[Last]++;
1060 NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
1062 if (isa<LoadInst>(Repl))
1064 else if (isa<StoreInst>(Repl))
1066 else if (isa<CallInst>(Repl))
1072 NumHoisted += NL + NS +
NC + NI;
1074 NumLoadsHoisted += NL;
1075 NumStoresHoisted += NS;
1076 NumCallsHoisted +=
NC;
1077 return {NI, NL +
NC + NS};
1082 std::pair<unsigned, unsigned> hoistExpressions(
Function &
F) {
1088 int InstructionNb = 0;
1105 if (
auto *
Load = dyn_cast<LoadInst>(&I1))
1107 else if (
auto *Store = dyn_cast<StoreInst>(&I1))
1109 else if (
auto *Call = dyn_cast<CallInst>(&I1)) {
1110 if (
auto *
Intr = dyn_cast<IntrinsicInst>(Call)) {
1111 if (isa<DbgInfoIntrinsic>(
Intr) ||
1116 if (Call->mayHaveSideEffects())
1119 if (Call->isConvergent())
1123 }
else if (HoistingGeps || !isa<GetElementPtrInst>(&I1))
1152 if (skipFunction(F))
1154 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1155 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
1156 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
1157 auto &MD = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
1158 auto &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
1198 "Early GVN Hoisting of Expressions",
false,
false)
Legacy wrapper pass to provide the GlobalsAAResult object.
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static cl::opt< int > MaxDepthInBB("gvn-hoist-max-depth", cl::Hidden, cl::init(100), cl::desc("Hoist instructions from the beginning of the BB up to the " "maximum specified depth (default = 100, unlimited = -1)"))
static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
gvn hoist
When an instruction is found to only use loop invariant operands that is safe to hoist, this instruction is called to do the dirty work.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Provides a lazy, caching interface for making common memory aliasing information queries, backed by LLVM's alias analysis passes.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Value * getPointerOperand(Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool doesNotAccessMemory(unsigned OpNo) const
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.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
This is the interface for a simple mod/ref and alias analysis over globals.
void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs)
Drop all unknown metadata except for debug locations.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
This class represents a function call, abstracting a target machine's calling convention.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
bool isTerminator() const
unsigned int rank(const Value *V) const
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 properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
FunctionPass * createGVNHoistPass()
An instruction for reading from memory.
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
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 defines the Use class.
static void combineKnownMetadata(Instruction *ReplInst, Instruction *I)
gvn Early GVN Hoisting of Expressions
Represents read-only accesses to memory.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static uint32_t getAlignment(const MCSectionCOFF &Sec)
Legacy analysis pass which computes MemorySSA.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
A Use represents the edge between a Value definition and its users.
void setDefiningBlocks(const SmallPtrSetImpl< BasicBlock *> &Blocks)
Give the IDF calculator the set of blocks in which the value is defined.
static bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Encapsulates MemorySSA, including all data associated with memory accesses.
void insert(Instruction *I, GVN::ValueTable &VN)
An analysis that produces MemoryDependenceResults for a function.
static cl::opt< int > MaxChainLength("gvn-hoist-max-chain-length", cl::Hidden, cl::init(10), cl::desc("Maximum length of dependent chains to hoist " "(default = 10, unlimited = -1)"))
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
INITIALIZE_PASS_BEGIN(GVNHoistLegacyPass, "gvn-hoist", "Early GVN Hoisting of Expressions", false, false) INITIALIZE_PASS_END(GVNHoistLegacyPass
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
void insert(LoadInst *Load, GVN::ValueTable &VN)
The core GVN pass object.
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction...
void combineMetadata(Instruction *K, const Instruction *J, ArrayRef< unsigned > KnownIDs, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
const VNtoInsns & getVNTable() const
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
const VNtoInsns & getLoadVNTable() const
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
Value * getOperand(unsigned i) const
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
idf_iterator< T > idf_begin(const T &G)
iterator find(const_arg_type_t< KeyT > Val)
idf_iterator< T > idf_end(const T &G)
const BasicBlock & getEntryBlock() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
void insert(CallInst *Call, GVN::ValueTable &VN)
initializer< Ty > init(const Ty &Val)
bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
const VNtoInsns & getScalarVNTable() const
This class holds the mapping between values and value numbers.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
SmallVector< Instruction *, 4 > SmallVecInsn
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
std::pair< iterator, bool > insert(const ValueT &V)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool mayThrow() const
Return true if this instruction may throw an exception.
const VNtoInsns & getStoreVNTable() const
Represent the analysis usage information of a pass.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Analysis pass providing a never-invalidated alias analysis result.
FunctionPass class - This class is used to implement most global optimizations.
Value * getPointerOperand()
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Compute iterated dominance frontiers using a linear time algorithm.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance...
An intrusive list with ownership and callbacks specified/controlled by ilist_traits, only with API safe for polymorphic types.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
static cl::opt< int > MaxNumberOfBBSInPath("gvn-hoist-max-bbs", cl::Hidden, cl::init(4), cl::desc("Max number of basic blocks on the path between " "hoisting locations (default = 4, unlimited = -1)"))
const VNtoInsns & getVNTable() const
std::pair< unsigned, unsigned > VNType
bool operator==(const CHIArg &A)
void sort(IteratorTy Start, IteratorTy End)
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches, switches, etc.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
void calculate(SmallVectorImpl< BasicBlock *> &IDFBlocks)
Calculate iterated dominance frontiers.
bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in the same basic block, determine whether MemoryAccess A dominates MemoryA...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Analysis pass which computes a PostDominatorTree.
An analysis that produces MemorySSA for a function.
BasicBlock * getBlock() const
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
pred_range predecessors(BasicBlock *BB)
GVNHoist(DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA, MemoryDependenceResults *MD, MemorySSA *MSSA)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
A range adaptor for a pair of iterators.
std::pair< BasicBlock *, SmallVecInsn > HoistingPointInfo
Class that has the common methods + fields of memory uses/defs.
typename SuperClass::iterator iterator
iterator_range< user_iterator > users()
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
void insert(StoreInst *Store, GVN::ValueTable &VN)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void initializeGVNHoistLegacyPassPass(PassRegistry &)
StringRef getName() const
Return a constant reference to the value's name.
bool onlyReadsMemory(unsigned OpNo) const
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.
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
uint32_t lookupOrAdd(Value *V)
lookup_or_add - Returns the value number for the specified value, assigning it a new number if it did...
const VNtoInsns & getVNTable() 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...
static cl::opt< int > MaxHoistedThreshold("gvn-max-hoisted", cl::Hidden, cl::init(-1), cl::desc("Max number of instructions to hoist " "(default unlimited = -1)"))
iterator_range< df_iterator< T > > depth_first(const T &G)
Determine the iterated dominance frontier, given a set of defining blocks, and optionally, a set of live-in blocks.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isEHPad() const
Return true if this basic block is an exception handling block.
LLVM Value Representation.
void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
succ_range successors(Instruction *I)
SmallVectorImpl< CHIArg >::iterator CHIIt
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
Represents phi nodes for memory accesses.
Utility type to build an inheritance chain that makes it easy to rank overload candidates.
This header defines various interfaces for pass management in LLVM.
bool operator!=(const CHIArg &A)
Value * getPointerOperand()
const BasicBlock * getParent() const