78#define DEBUG_TYPE "gvn-hoist"
80STATISTIC(NumHoisted,
"Number of instructions hoisted");
81STATISTIC(NumRemoved,
"Number of instructions removed");
82STATISTIC(NumLoadsHoisted,
"Number of loads hoisted");
83STATISTIC(NumLoadsRemoved,
"Number of loads removed");
84STATISTIC(NumStoresHoisted,
"Number of stores hoisted");
85STATISTIC(NumStoresRemoved,
"Number of stores removed");
86STATISTIC(NumCallsHoisted,
"Number of calls hoisted");
87STATISTIC(NumCallsRemoved,
"Number of calls removed");
91 cl::desc(
"Max number of instructions to hoist "
92 "(default unlimited = -1)"));
96 cl::desc(
"Max number of basic blocks on the path between "
97 "hoisting locations (default = 4, unlimited = -1)"));
101 cl::desc(
"Hoist instructions from the beginning of the BB up to the "
102 "maximum specified depth (default = 100, unlimited = -1)"));
106 cl::desc(
"Maximum length of dependent chains to hoist "
107 "(default = 10, unlimited = -1)"));
122using VNType = std::pair<unsigned, uintptr_t>;
181 if (
Load->isSimple()) {
200 if (!
Store->isSimple())
224 auto Entry = std::make_pair(V,
InvalidVN);
226 if (
Call->doesNotAccessMemory())
227 VNtoCallsScalars[Entry].push_back(
Call);
228 else if (
Call->onlyReadsMemory())
229 VNtoCallsLoads[Entry].push_back(
Call);
231 VNtoCallsStores[Entry].push_back(
Call);
246 : DT(DT), PDT(PDT), AA(AA), MSSA(MSSA),
248 MSSA->ensureOptimizedUses();
267 std::unique_ptr<MemorySSAUpdater> MSSAUpdater;
272 unsigned NumFuncArgs;
273 const bool HoistingGeps =
false;
283 unsigned I1DFS = DFSNumber.
lookup(I1);
284 unsigned I2DFS = DFSNumber.
lookup(I2);
286 return I1DFS < I2DFS;
290 bool hasMemoryUse(
const Instruction *NewPt, MemoryDef *Def,
291 const BasicBlock *BB);
293 bool hasEHhelper(
const BasicBlock *BB,
const BasicBlock *SrcBB,
294 int &NBBsOnAllPaths);
303 bool hasEHOrLoadsOnPath(
const Instruction *NewPt, MemoryDef *Def,
304 int &NBBsOnAllPaths);
310 bool hasEHOnPath(
const BasicBlock *HoistPt,
const BasicBlock *SrcBB,
311 int &NBBsOnAllPaths);
315 bool safeToHoistLdSt(
const Instruction *NewPt,
const Instruction *OldPt,
316 MemoryUseOrDef *U, InsKind K,
int &NBBsOnAllPaths);
320 bool safeToHoistScalar(
const BasicBlock *HoistBB,
const BasicBlock *BB,
321 int &NBBsOnAllPaths) {
322 return !hasEHOnPath(HoistBB, BB, NBBsOnAllPaths);
339 bool valueAnticipable(
CHIArgs C, Instruction *TI)
const;
343 void checkSafety(
CHIArgs C, BasicBlock *BB, InsKind K,
344 SmallVectorImpl<CHIArg> &Safe);
346 using RenameStackType = DenseMap<VNType, SmallVector<Instruction *, 2>>;
349 void fillRenameStack(BasicBlock *BB,
InValuesType &ValueBBs,
350 RenameStackType &RenameStack);
353 RenameStackType &RenameStack);
360 auto Root = PDT->getNode(
nullptr);
369 RenameStackType RenameStack;
371 fillRenameStack(BB, ValueBBs, RenameStack);
374 fillChiArgs(BB, CHIBBs, RenameStack);
382 void findHoistableCandidates(
OutValuesType &CHIBBs, InsKind K,
390 std::vector<VNType> Ranks;
391 for (
const auto &Entry : Map) {
392 Ranks.push_back(
Entry.first);
414 for (
const auto &R : Ranks) {
419 SmallPtrSet<BasicBlock *, 2> VNBlocks;
420 for (
const auto &
I : V) {
431 IDFs.setDefiningBlocks(VNBlocks);
433 IDFs.calculate(IDFBlocks);
436 for (
unsigned i = 0; i <
V.size(); ++i) {
437 InValue[
V[i]->getParent()].push_back(std::make_pair(VN, V[i]));
441 CHIArg EmptyChi = {VN,
nullptr,
nullptr};
442 for (
auto *IDFBB : IDFBlocks) {
443 for (
unsigned i = 0; i <
V.size(); ++i) {
445 if (DT->properlyDominates(IDFBB, V[i]->getParent())) {
446 OutValue[IDFBB].push_back(EmptyChi);
448 << IDFBB->getName() <<
", for Insn: " << *V[i]);
456 insertCHI(InValue, OutValue);
458 findHoistableCandidates(OutValue, K, HPL);
465 bool allOperandsAvailable(
const Instruction *
I,
466 const BasicBlock *HoistPt)
const;
469 bool allGepOperandsAvailable(
const Instruction *
I,
470 const BasicBlock *HoistPt)
const;
473 void makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
475 Instruction *Gep)
const;
477 void updateAlignment(Instruction *
I, Instruction *Repl);
481 unsigned rauw(
const SmallVecInsn &Candidates, Instruction *Repl,
482 MemoryUseOrDef *NewMemAcc);
485 void raMPHIuw(MemoryUseOrDef *NewMemAcc);
488 unsigned removeAndReplace(
const SmallVecInsn &Candidates, Instruction *Repl,
489 BasicBlock *DestBB,
bool MoveAccess);
494 bool makeGepOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt,
501 std::pair<unsigned, unsigned> hoistExpressions(Function &
F);
505 NumFuncArgs =
F.arg_size();
507 VN.setAliasAnalysis(AA);
509 VN.setMemorySSA(MSSA,
true);
514 DFSNumber[BB] = ++BBI;
516 for (
const auto &Inst : *BB)
517 DFSNumber[&Inst] = ++
I;
527 auto HoistStat = hoistExpressions(
F);
528 if (HoistStat.first + HoistStat.second == 0)
531 if (HoistStat.second > 0)
554 return 3 +
A->getArgNo();
558 auto Result = DFSNumber.lookup(V);
560 return 4 + NumFuncArgs + Result;
566 auto [It, Inserted] = BBSideEffects.
try_emplace(BB);
592 bool ReachedNewPt =
false;
594 for (
const MemoryAccess &MA : *Acc)
599 if (BB == OldBB && firstInBB(OldPt, Insn))
605 if (firstInBB(Insn, NewPt))
618 int &NBBsOnAllPaths) {
620 if (NBBsOnAllPaths == 0)
630 if ((BB != SrcBB) && HoistBarrier.count(BB))
637 int &NBBsOnAllPaths) {
640 assert(DT->dominates(NewBB, OldBB) &&
"invalid path");
641 assert(DT->dominates(
Def->getDefiningAccess()->getBlock(), NewBB) &&
642 "def does not dominate new hoisting point");
656 if (hasEHhelper(BB, OldBB, NBBsOnAllPaths))
660 if (hasMemoryUse(NewPt, Def, BB))
664 if (NBBsOnAllPaths != -1)
674 int &NBBsOnAllPaths) {
675 assert(DT->dominates(HoistPt, SrcBB) &&
"Invalid path");
690 if (hasEHhelper(BB, SrcBB, NBBsOnAllPaths))
694 if (NBBsOnAllPaths != -1)
703bool GVNHoist::safeToHoistLdSt(
const Instruction *NewPt,
705 GVNHoist::InsKind K,
int &NBBsOnAllPaths) {
715 MemoryAccess *
D =
U->getDefiningAccess();
717 if (DT->properlyDominates(NewBB, DBB))
721 if (NewBB == DBB && !MSSA->isLiveOnEntryDef(
D))
723 if (!firstInBB(UD->getMemoryInst(), NewPt))
728 if (K == InsKind::Store) {
731 }
else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
735 if (DT->properlyDominates(DBB, NewBB))
738 assert(MSSA->locallyDominates(
D, U));
770 if (K == InsKind::Scalar) {
771 if (safeToHoistScalar(BB, Insn->
getParent(), NumBBsOnAllPaths))
774 if (MemoryUseOrDef *UD = MSSA->getMemoryAccess(Insn))
775 if (safeToHoistLdSt(
T, Insn, UD, K, NumBBsOnAllPaths))
782 GVNHoist::RenameStackType &RenameStack) {
783 auto it1 = ValueBBs.find(BB);
784 if (it1 != ValueBBs.end()) {
787 <<
" for pushing instructions on stack";);
788 for (std::pair<VNType, Instruction *> &VI :
reverse(it1->second)) {
791 RenameStack[
VI.first].push_back(
VI.second);
797 GVNHoist::RenameStackType &RenameStack) {
800 auto P = CHIBBs.find(Pred);
801 if (
P == CHIBBs.end()) {
804 LLVM_DEBUG(
dbgs() <<
"\nLooking at CHIs in: " << Pred->getName(););
807 auto &VCHI =
P->second;
808 for (
auto It = VCHI.begin(),
E = VCHI.end(); It !=
E;) {
811 auto si = RenameStack.find(
C.VN);
815 if (si != RenameStack.end() && si->second.size() &&
816 DT->properlyDominates(Pred, si->second.back()->getParent())) {
818 C.I = si->second.pop_back_val();
820 <<
"\nCHI Inserted in BB: " <<
C.Dest->getName() << *
C.I
821 <<
", VN: " <<
C.VN.first <<
", " <<
C.VN.second);
834 auto cmpVN = [](
const CHIArg &
A,
const CHIArg &
B) {
return A.VN <
B.VN; };
840 SmallVectorImpl<CHIArg> &CHIs =
A.second;
849 auto PrevIt = CHIs.
begin();
850 while (PrevIt != PHIIt) {
857 checkSafety(
make_range(PrevIt, PHIIt), BB, K, Safe);
869 PHIIt = std::find_if(PrevIt, CHIs.
end(),
870 [PrevIt](CHIArg &
A) { return A != *PrevIt; });
875bool GVNHoist::allOperandsAvailable(
const Instruction *
I,
877 for (
const Use &
Op :
I->operands())
879 if (!DT->dominates(Inst->getParent(), HoistPt))
885bool GVNHoist::allGepOperandsAvailable(
const Instruction *
I,
887 for (
const Use &
Op :
I->operands())
889 if (!DT->dominates(Inst->getParent(), HoistPt)) {
890 if (
const GetElementPtrInst *GepOp =
892 if (!allGepOperandsAvailable(GepOp, HoistPt))
907 assert(allGepOperandsAvailable(Gep, HoistPt) &&
"GEP operands not available");
913 if (DT->dominates(
Op->getParent(), HoistPt))
919 makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
931 for (
const Instruction *OtherInst : InstructionsToHoist) {
932 const GetElementPtrInst *OtherGep;
943 if (OtherGep != Gep) {
955 ReplacementLoad->setAlignment(
959 ReplacementStore->setAlignment(
963 ReplacementAlloca->setAlignment(std::max(ReplacementAlloca->getAlign(),
973 for (Instruction *
I : Candidates) {
976 updateAlignment(
I, Repl);
979 MemoryAccess *OldMA = MSSA->getMemoryAccess(
I);
981 MSSAUpdater->removeMemoryAccess(OldMA);
982 }
else if (MemoryAccess *OldMA = MSSA->getMemoryAccess(
I)) {
983 MSSAUpdater->removeMemoryAccess(OldMA);
988 I->replaceAllUsesWith(Repl);
989 I->eraseFromParent();
996 SmallPtrSet<MemoryPhi *, 4> UsePhis;
997 for (User *U : NewMemAcc->
users())
1001 for (MemoryPhi *Phi : UsePhis) {
1002 auto In =
Phi->incoming_values();
1004 Phi->replaceAllUsesWith(NewMemAcc);
1005 MSSAUpdater->removeMemoryAccess(Phi);
1010unsigned GVNHoist::removeAndReplace(
const SmallVecInsn &Candidates,
1013 MemoryUseOrDef *NewMemAcc = MSSA->getMemoryAccess(Repl);
1014 if (MoveAccess && NewMemAcc) {
1021 unsigned NR = rauw(Candidates, Repl, NewMemAcc);
1025 raMPHIuw(NewMemAcc);
1029bool GVNHoist::makeGepOperandsAvailable(
1033 GetElementPtrInst *Gep =
nullptr;
1044 if (!allGepOperandsAvailable(Val, HoistPt))
1046 }
else if (!DT->dominates(Val->
getParent(), HoistPt))
1052 if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
1055 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
1058 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
1064 unsigned NI = 0, NL = 0, NS = 0,
NC = 0, NR = 0;
1071 for (Instruction *
I : InstructionsToHoist)
1072 if (
I->getParent() == DestBB)
1076 if (!Repl || firstInBB(
I, Repl))
1081 bool MoveAccess =
true;
1084 assert(allOperandsAvailable(Repl, DestBB) &&
1085 "instruction depends on operands that are not available");
1090 Repl = InstructionsToHoist.front();
1095 if (!allOperandsAvailable(Repl, DestBB)) {
1102 if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
1108 if (
auto *MUD = MSSA->getMemoryAccess(Repl))
1112 DFSNumber[Repl] = DFSNumber[
Last]++;
1117 NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
1130 MSSA->verifyMemorySSA();
1132 NumHoisted += NL + NS +
NC + NI;
1134 NumLoadsHoisted += NL;
1135 NumStoresHoisted += NS;
1136 NumCallsHoisted +=
NC;
1137 return {NI, NL +
NC + NS};
1140std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(
Function &
F) {
1145 for (BasicBlock *BB :
depth_first(&
F.getEntryBlock())) {
1146 int InstructionNb = 0;
1147 for (Instruction &I1 : *BB) {
1151 HoistBarrier.insert(BB);
1160 if (
I1.isTerminator())
1164 LI.insert(Load, VN);
1166 SI.insert(Store, VN);
1169 if (Intr->getIntrinsicID() == Intrinsic::assume ||
1170 Intr->getIntrinsicID() == Intrinsic::sideeffect)
1179 CI.insert(
Call, VN);
1190 computeInsertionPoints(
II.getVNTable(), HPL, InsKind::Scalar);
1191 computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load);
1192 computeInsertionPoints(
SI.getVNTable(), HPL, InsKind::Store);
1193 computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar);
1194 computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load);
1195 computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 defines the DenseSet and SmallDenseSet classes.
static cl::opt< int > MaxHoistedThreshold("gvn-max-hoisted", cl::Hidden, cl::init(-1), cl::desc("Max number of instructions to hoist " "(default unlimited = -1)"))
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)"))
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 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)"))
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
uint64_t IntrinsicInst * II
static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
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 manager for alias analyses.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
bool isConvergent() const
Determine if the invoke is convergent.
void insert(CallInst *Call, GVNPass::ValueTable &VN)
const VNtoInsns & getLoadVNTable() const
const VNtoInsns & getScalarVNTable() const
const VNtoInsns & getStoreVNTable() const
This class represents a function call, abstracting a target machine's calling convention.
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.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
GVNHoist(DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA, MemorySSA *MSSA)
unsigned int rank(const Value *V) const
This class holds the mapping between values and value numbers.
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
const VNtoInsns & getVNTable() const
void insert(Instruction *I, GVNPass::ValueTable &VN)
LLVM_ABI bool mayThrow(bool IncludePhaseOneUnwind=false) const LLVM_READONLY
Return true if this instruction may throw an exception.
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI void dropLocation()
Drop the instruction's debug location.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
LLVM_ABI void applyMergedLocation(DebugLoc LocA, DebugLoc LocB)
Merge 2 debug locations and apply it to the Instruction.
const VNtoInsns & getVNTable() const
void insert(LoadInst *Load, GVNPass::ValueTable &VN)
An instruction for reading from memory.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
An analysis that produces MemorySSA for a function.
static LLVM_ABI bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA)
Encapsulates MemorySSA, including all data associated with memory accesses.
iplist< MemoryAccess, ilist_tag< MSSAHelpers::AllAccessTag > > AccessList
Class that has the common methods + fields of memory uses/defs.
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
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.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void insert(StoreInst *Store, GVNPass::ValueTable &VN)
const VNtoInsns & getVNTable() const
An instruction for storing to memory.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
NodeAddr< PhiNode * > Phi
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
DenseMap< BasicBlock *, SmallVector< std::pair< VNType, Instruction * >, 2 > > InValuesType
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
void stable_sort(R &&Range)
SmallVector< HoistingPointInfo, 4 > HoistingPointList
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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.
@ Unknown
Not known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
SmallVectorImpl< Instruction * > SmallVecImplInsn
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
SmallVector< Instruction *, 4 > SmallVecInsn
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
SmallVectorImpl< CHIArg >::iterator CHIIt
DenseMap< VNType, SmallVector< Instruction *, 4 > > VNtoInsns
auto reverse(ContainerTy &&C)
std::pair< unsigned, uintptr_t > VNType
IDFCalculator< true > ReverseIDFCalculator
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::pair< BasicBlock *, SmallVecInsn > HoistingPointInfo
idf_iterator< T > idf_end(const T &G)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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 combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
DWARFExpression::Operation Op
idf_iterator< T > idf_begin(const T &G)
DenseMap< BasicBlock *, SmallVector< CHIArg, 2 > > OutValuesType
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
iterator_range< CHIIt > CHIArgs
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
DenseMap< const BasicBlock *, bool > BBSideEffectsSet
Implement std::hash so that hash_code can be used in STL containers.
bool operator!=(const CHIArg &A) const
bool operator==(const CHIArg &A) const
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.