79#define DEBUG_TYPE "gvn-hoist"
81STATISTIC(NumHoisted,
"Number of instructions hoisted");
82STATISTIC(NumRemoved,
"Number of instructions removed");
83STATISTIC(NumLoadsHoisted,
"Number of loads hoisted");
84STATISTIC(NumLoadsRemoved,
"Number of loads removed");
85STATISTIC(NumStoresHoisted,
"Number of stores hoisted");
86STATISTIC(NumStoresRemoved,
"Number of stores removed");
87STATISTIC(NumCallsHoisted,
"Number of calls hoisted");
88STATISTIC(NumCallsRemoved,
"Number of calls removed");
103using VNType = std::pair<unsigned, uintptr_t>;
162 if (
Load->isSimple()) {
181 if (!
Store->isSimple())
205 auto Entry = std::make_pair(V,
InvalidVN);
207 if (
Call->doesNotAccessMemory())
208 VNtoCallsScalars[Entry].push_back(
Call);
209 else if (
Call->onlyReadsMemory())
210 VNtoCallsLoads[Entry].push_back(
Call);
212 VNtoCallsStores[Entry].push_back(
Call);
227 : Opts(ScalarOptions::
Global), DT(DT), PDT(PDT), AA(AA), MSSA(MSSA),
229 MSSA->ensureOptimizedUses();
243 const ScalarOptions &Opts;
249 std::unique_ptr<MemorySSAUpdater> MSSAUpdater;
254 unsigned NumFuncArgs;
255 const bool HoistingGeps =
false;
265 unsigned I1DFS = DFSNumber.
lookup(I1);
266 unsigned I2DFS = DFSNumber.
lookup(I2);
268 return I1DFS < I2DFS;
272 bool hasMemoryUse(
const Instruction *NewPt, MemoryDef *Def,
273 const BasicBlock *BB);
275 bool hasEHhelper(
const BasicBlock *BB,
const BasicBlock *SrcBB,
276 int &NBBsOnAllPaths);
285 bool hasEHOrLoadsOnPath(
const Instruction *NewPt, MemoryDef *Def,
286 int &NBBsOnAllPaths);
292 bool hasEHOnPath(
const BasicBlock *HoistPt,
const BasicBlock *SrcBB,
293 int &NBBsOnAllPaths);
297 bool safeToHoistLdSt(
const Instruction *NewPt,
const Instruction *OldPt,
298 MemoryUseOrDef *U, InsKind K,
int &NBBsOnAllPaths);
302 bool safeToHoistScalar(
const BasicBlock *HoistBB,
const BasicBlock *BB,
303 int &NBBsOnAllPaths) {
304 return !hasEHOnPath(HoistBB, BB, NBBsOnAllPaths);
321 bool valueAnticipable(
CHIArgs C, Instruction *TI)
const;
325 void checkSafety(
CHIArgs C, BasicBlock *BB, InsKind K,
326 SmallVectorImpl<CHIArg> &Safe);
328 using RenameStackType = DenseMap<VNType, SmallVector<Instruction *, 2>>;
331 void fillRenameStack(BasicBlock *BB,
InValuesType &ValueBBs,
332 RenameStackType &RenameStack);
335 RenameStackType &RenameStack);
342 auto Root = PDT->getNode(
nullptr);
351 RenameStackType RenameStack;
353 fillRenameStack(BB, ValueBBs, RenameStack);
356 fillChiArgs(BB, CHIBBs, RenameStack);
364 void findHoistableCandidates(
OutValuesType &CHIBBs, InsKind K,
372 std::vector<VNType> Ranks;
373 for (
const auto &Entry : Map) {
374 Ranks.push_back(
Entry.first);
396 for (
const auto &R : Ranks) {
401 SmallPtrSet<BasicBlock *, 2> VNBlocks;
402 for (
const auto &
I : V) {
413 IDFs.setDefiningBlocks(VNBlocks);
415 IDFs.calculate(IDFBlocks);
418 for (
unsigned i = 0; i <
V.size(); ++i) {
419 InValue[
V[i]->getParent()].push_back(std::make_pair(VN, V[i]));
423 CHIArg EmptyChi = {VN,
nullptr,
nullptr};
424 for (
auto *IDFBB : IDFBlocks) {
425 for (
unsigned i = 0; i <
V.size(); ++i) {
427 if (DT->properlyDominates(IDFBB, V[i]->getParent())) {
428 OutValue[IDFBB].push_back(EmptyChi);
430 << IDFBB->getName() <<
", for Insn: " << *V[i]);
438 insertCHI(InValue, OutValue);
440 findHoistableCandidates(OutValue, K, HPL);
447 bool allOperandsAvailable(
const Instruction *
I,
448 const BasicBlock *HoistPt)
const;
451 bool allGepOperandsAvailable(
const Instruction *
I,
452 const BasicBlock *HoistPt)
const;
455 void makeGepsAvailable(Instruction *Repl, BasicBlock *HoistPt,
457 Instruction *Gep)
const;
459 void updateAlignment(Instruction *
I, Instruction *Repl);
463 unsigned rauw(
const SmallVecInsn &Candidates, Instruction *Repl,
464 MemoryUseOrDef *NewMemAcc);
467 void raMPHIuw(MemoryUseOrDef *NewMemAcc);
470 unsigned removeAndReplace(
const SmallVecInsn &Candidates, Instruction *Repl,
471 BasicBlock *DestBB,
bool MoveAccess);
476 bool makeGepOperandsAvailable(Instruction *Repl, BasicBlock *HoistPt,
483 std::pair<unsigned, unsigned> hoistExpressions(
Function &
F);
487 NumFuncArgs =
F.arg_size();
489 VN.setAliasAnalysis(AA);
491 VN.setMemorySSA(MSSA,
true);
496 DFSNumber[BB] = ++BBI;
498 for (
const auto &Inst : *BB)
499 DFSNumber[&Inst] = ++
I;
506 if (Opts.gvn_hoist_max_chain_length != -1 &&
507 ++ChainLength >= Opts.gvn_hoist_max_chain_length)
510 auto HoistStat = hoistExpressions(
F);
511 if (HoistStat.first + HoistStat.second == 0)
514 if (HoistStat.second > 0)
537 return 3 +
A->getArgNo();
541 auto Result = DFSNumber.lookup(V);
543 return 4 + NumFuncArgs + Result;
549 auto [It, Inserted] = BBSideEffects.
try_emplace(BB);
575 bool ReachedNewPt =
false;
577 for (
const MemoryAccess &MA : *Acc)
582 if (BB == OldBB && firstInBB(OldPt, Insn))
588 if (firstInBB(Insn, NewPt))
601 int &NBBsOnAllPaths) {
603 if (NBBsOnAllPaths == 0)
613 if ((BB != SrcBB) && HoistBarrier.count(BB))
620 int &NBBsOnAllPaths) {
623 assert(DT->dominates(NewBB, OldBB) &&
"invalid path");
624 assert(DT->dominates(
Def->getDefiningAccess()->getBlock(), NewBB) &&
625 "def does not dominate new hoisting point");
639 if (hasEHhelper(BB, OldBB, NBBsOnAllPaths))
643 if (hasMemoryUse(NewPt, Def, BB))
647 if (NBBsOnAllPaths != -1)
657 int &NBBsOnAllPaths) {
658 assert(DT->dominates(HoistPt, SrcBB) &&
"Invalid path");
673 if (hasEHhelper(BB, SrcBB, NBBsOnAllPaths))
677 if (NBBsOnAllPaths != -1)
686bool GVNHoist::safeToHoistLdSt(
const Instruction *NewPt,
688 GVNHoist::InsKind K,
int &NBBsOnAllPaths) {
698 MemoryAccess *
D =
U->getDefiningAccess();
700 if (DT->properlyDominates(NewBB, DBB))
704 if (NewBB == DBB && !MSSA->isLiveOnEntryDef(
D))
706 if (!firstInBB(UD->getMemoryInst(), NewPt))
711 if (K == InsKind::Store) {
714 }
else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
718 if (DT->properlyDominates(DBB, NewBB))
721 assert(MSSA->locallyDominates(
D, U));
742 int NumBBsOnAllPaths = Opts.gvn_hoist_max_bbs;
753 if (K == InsKind::Scalar) {
754 if (safeToHoistScalar(BB, Insn->
getParent(), NumBBsOnAllPaths))
757 if (MemoryUseOrDef *UD = MSSA->getMemoryAccess(Insn))
758 if (safeToHoistLdSt(
T, Insn, UD, K, NumBBsOnAllPaths))
765 GVNHoist::RenameStackType &RenameStack) {
766 auto it1 = ValueBBs.find(BB);
767 if (it1 != ValueBBs.end()) {
770 <<
" for pushing instructions on stack";);
771 for (std::pair<VNType, Instruction *> &VI :
reverse(it1->second)) {
774 RenameStack[
VI.first].push_back(
VI.second);
780 GVNHoist::RenameStackType &RenameStack) {
783 auto P = CHIBBs.find(Pred);
784 if (
P == CHIBBs.end()) {
787 LLVM_DEBUG(
dbgs() <<
"\nLooking at CHIs in: " << Pred->getName(););
790 auto &VCHI =
P->second;
791 for (
auto It = VCHI.begin(),
E = VCHI.end(); It !=
E;) {
794 auto si = RenameStack.find(
C.VN);
798 if (si != RenameStack.end() && si->second.size() &&
799 DT->properlyDominates(Pred, si->second.back()->getParent())) {
801 C.I = si->second.pop_back_val();
803 <<
"\nCHI Inserted in BB: " <<
C.Dest->getName() << *
C.I
804 <<
", VN: " <<
C.VN.first <<
", " <<
C.VN.second);
817 auto cmpVN = [](
const CHIArg &
A,
const CHIArg &
B) {
return A.VN <
B.VN; };
821 for (
auto &
A : CHIBBs) {
823 SmallVectorImpl<CHIArg> &CHIs =
A.second;
832 auto PrevIt = CHIs.
begin();
833 while (PrevIt != PHIIt) {
840 checkSafety(
make_range(PrevIt, PHIIt), BB, K, Safe);
852 PHIIt = std::find_if(PrevIt, CHIs.
end(),
853 [PrevIt](CHIArg &
A) { return A != *PrevIt; });
858bool GVNHoist::allOperandsAvailable(
const Instruction *
I,
860 for (
const Use &
Op :
I->operands())
862 if (!DT->dominates(Inst->getParent(), HoistPt))
868bool GVNHoist::allGepOperandsAvailable(
const Instruction *
I,
870 for (
const Use &
Op :
I->operands())
872 if (!DT->dominates(Inst->getParent(), HoistPt)) {
873 if (
const GetElementPtrInst *GepOp =
875 if (!allGepOperandsAvailable(GepOp, HoistPt))
890 assert(allGepOperandsAvailable(Gep, HoistPt) &&
"GEP operands not available");
896 if (DT->dominates(
Op->getParent(), HoistPt))
902 makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
914 for (
const Instruction *OtherInst : InstructionsToHoist) {
915 const GetElementPtrInst *OtherGep;
926 if (OtherGep != Gep) {
938 ReplacementLoad->setAlignment(
942 ReplacementStore->setAlignment(
946 ReplacementAlloca->setAlignment(std::max(ReplacementAlloca->getAlign(),
956 for (Instruction *
I : Candidates) {
959 updateAlignment(
I, Repl);
962 MemoryAccess *OldMA = MSSA->getMemoryAccess(
I);
964 MSSAUpdater->removeMemoryAccess(OldMA);
965 }
else if (MemoryAccess *OldMA = MSSA->getMemoryAccess(
I)) {
966 MSSAUpdater->removeMemoryAccess(OldMA);
971 I->replaceAllUsesWith(Repl);
972 I->eraseFromParent();
979 SmallPtrSet<MemoryPhi *, 4> UsePhis;
980 for (User *U : NewMemAcc->
users())
984 for (MemoryPhi *Phi : UsePhis) {
985 auto In =
Phi->incoming_values();
987 Phi->replaceAllUsesWith(NewMemAcc);
988 MSSAUpdater->removeMemoryAccess(Phi);
993unsigned GVNHoist::removeAndReplace(
const SmallVecInsn &Candidates,
996 MemoryUseOrDef *NewMemAcc = MSSA->getMemoryAccess(Repl);
997 if (MoveAccess && NewMemAcc) {
1004 unsigned NR = rauw(Candidates, Repl, NewMemAcc);
1008 raMPHIuw(NewMemAcc);
1012bool GVNHoist::makeGepOperandsAvailable(
1016 GetElementPtrInst *Gep =
nullptr;
1027 if (!allGepOperandsAvailable(Val, HoistPt))
1029 }
else if (!DT->dominates(Val->
getParent(), HoistPt))
1035 if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
1038 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
1041 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
1047 unsigned NI = 0, NL = 0, NS = 0,
NC = 0, NR = 0;
1054 for (Instruction *
I : InstructionsToHoist)
1055 if (
I->getParent() == DestBB)
1059 if (!Repl || firstInBB(
I, Repl))
1064 bool MoveAccess =
true;
1067 assert(allOperandsAvailable(Repl, DestBB) &&
1068 "instruction depends on operands that are not available");
1073 Repl = InstructionsToHoist.front();
1078 if (!allOperandsAvailable(Repl, DestBB)) {
1085 if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
1091 if (
auto *MUD = MSSA->getMemoryAccess(Repl))
1095 DFSNumber[Repl] = DFSNumber[
Last]++;
1100 NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
1113 MSSA->verifyMemorySSA();
1115 NumHoisted += NL + NS +
NC + NI;
1117 NumLoadsHoisted += NL;
1118 NumStoresHoisted += NS;
1119 NumCallsHoisted +=
NC;
1120 return {NI, NL +
NC + NS};
1123std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(
Function &
F) {
1128 for (BasicBlock *BB :
depth_first(&
F.getEntryBlock())) {
1129 int InstructionNb = 0;
1130 for (Instruction &I1 : *BB) {
1134 HoistBarrier.insert(BB);
1139 if (Opts.gvn_hoist_max_depth != -1 &&
1140 InstructionNb++ >= Opts.gvn_hoist_max_depth)
1144 if (
I1.isTerminator())
1148 LI.insert(Load, VN);
1150 SI.insert(Store, VN);
1153 if (Intr->getIntrinsicID() == Intrinsic::assume ||
1154 Intr->getIntrinsicID() == Intrinsic::sideeffect)
1163 CI.insert(
Call, VN);
1174 computeInsertionPoints(
II.getVNTable(), HPL, InsKind::Scalar);
1175 computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load);
1176 computeInsertionPoints(
SI.getVNTable(), HPL, InsKind::Store);
1177 computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar);
1178 computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load);
1179 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.
This file provides the interface for the GVNHoist pass.
This file provides a data structure for mapping values and expressions to congruence class IDs.
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, GVNValueTable &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)
void insert(Instruction *I, GVNValueTable &VN)
const VNtoInsns & getVNTable() const
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, GVNValueTable &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, GVNValueTable &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.
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...
@ Global
Append to llvm.global_dtors.
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.