Go to the documentation of this file.
83 #define DEBUG_TYPE "gvn-hoist"
85 STATISTIC(NumHoisted,
"Number of instructions hoisted");
86 STATISTIC(NumRemoved,
"Number of instructions removed");
87 STATISTIC(NumLoadsHoisted,
"Number of loads hoisted");
88 STATISTIC(NumLoadsRemoved,
"Number of loads removed");
89 STATISTIC(NumStoresHoisted,
"Number of stores hoisted");
90 STATISTIC(NumStoresRemoved,
"Number of stores removed");
91 STATISTIC(NumCallsHoisted,
"Number of calls hoisted");
92 STATISTIC(NumCallsRemoved,
"Number of calls removed");
96 cl::desc(
"Max number of instructions to hoist "
97 "(default unlimited = -1)"));
101 cl::desc(
"Max number of basic blocks on the path between "
102 "hoisting locations (default = 4, unlimited = -1)"));
106 cl::desc(
"Hoist instructions from the beginning of the BB up to the "
107 "maximum specified depth (default = 100, unlimited = -1)"));
111 cl::desc(
"Maximum length of dependent chains to hoist "
112 "(default = 10, unlimited = -1)"));
127 using VNType = std::pair<unsigned, uintptr_t>;
186 if (
Load->isSimple()) {
190 VNtoLoads[{V, (uintptr_t)
Load->getType()}].push_back(
Load);
205 if (!
Store->isSimple())
229 auto Entry = std::make_pair(V,
InvalidVN);
231 if (Call->doesNotAccessMemory())
232 VNtoCallsScalars[Entry].push_back(Call);
233 else if (Call->onlyReadsMemory())
234 VNtoCallsLoads[Entry].push_back(Call);
236 VNtoCallsStores[Entry].push_back(Call);
245 static const unsigned KnownIDs[] = {LLVMContext::MD_tbaa,
246 LLVMContext::MD_alias_scope,
247 LLVMContext::MD_noalias,
248 LLVMContext::MD_range,
249 LLVMContext::MD_fpmath,
250 LLVMContext::MD_invariant_load,
251 LLVMContext::MD_invariant_group,
252 LLVMContext::MD_access_group};
263 : DT(DT), PDT(PDT),
AA(
AA), MD(MD), MSSA(MSSA),
285 std::unique_ptr<MemorySSAUpdater> MSSAUpdater;
290 unsigned NumFuncArgs;
291 const bool HoistingGeps =
false;
293 enum InsKind { Unknown, Scalar, Load, Store };
301 unsigned I1DFS = DFSNumber.
lookup(
I1);
302 unsigned I2DFS = DFSNumber.
lookup(I2);
304 return I1DFS < I2DFS;
312 int &NBBsOnAllPaths);
322 int &NBBsOnAllPaths);
329 int &NBBsOnAllPaths);
339 int &NBBsOnAllPaths) {
340 return !hasEHOnPath(HoistBB,
BB, NBBsOnAllPaths);
368 RenameStackType &RenameStack);
371 RenameStackType &RenameStack);
378 auto Root = PDT->
getNode(
nullptr);
387 RenameStackType RenameStack;
389 fillRenameStack(
BB, ValueBBs, RenameStack);
392 fillChiArgs(
BB, CHIBBs, RenameStack);
400 void findHoistableCandidates(
OutValuesType &CHIBBs, InsKind K,
408 std::vector<VNType> Ranks;
409 for (
const auto &Entry : Map) {
410 Ranks.push_back(Entry.first);
432 for (
const auto &R : Ranks) {
449 IDFs.setDefiningBlocks(VNBlocks);
451 IDFs.calculate(IDFBlocks);
454 for (
unsigned i = 0;
i < V.size(); ++
i) {
455 InValue[V[
i]->getParent()].push_back(std::make_pair(VN, V[
i]));
459 CHIArg EmptyChi = {VN,
nullptr,
nullptr};
460 for (
auto *IDFBB : IDFBlocks) {
461 for (
unsigned i = 0;
i < V.size(); ++
i) {
464 OutValue[IDFBB].push_back(EmptyChi);
466 << IDFBB->getName() <<
", for Insn: " << *V[
i]);
474 insertCHI(InValue, OutValue);
476 findHoistableCandidates(OutValue, K, HPL);
519 std::pair<unsigned, unsigned> hoistExpressions(
Function &
F);
533 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
534 auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
535 auto &
AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
536 auto &MD = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
537 auto &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
556 NumFuncArgs =
F.arg_size();
558 VN.setAliasAnalysis(
AA);
564 DFSNumber[
BB] = ++BBI;
566 for (
auto &Inst : *
BB)
567 DFSNumber[&Inst] = ++
I;
577 auto HoistStat = hoistExpressions(
F);
578 if (HoistStat.first + HoistStat.second == 0)
581 if (HoistStat.second > 0)
597 if (isa<ConstantExpr>(V))
599 if (isa<UndefValue>(V))
601 if (isa<Constant>(V))
603 else if (
auto *A = dyn_cast<Argument>(V))
604 return 3 + A->getArgNo();
608 auto Result = DFSNumber.
lookup(V);
610 return 4 + NumFuncArgs + Result;
616 auto It = BBSideEffects.
find(
BB);
617 if (It != BBSideEffects.
end())
620 if (
BB->isEHPad() ||
BB->hasAddressTaken()) {
621 BBSideEffects[
BB] =
true;
625 if (
BB->getTerminator()->mayThrow()) {
626 BBSideEffects[
BB] =
true;
630 BBSideEffects[
BB] =
false;
643 bool ReachedNewPt =
false;
646 if (
const MemoryUse *MU = dyn_cast<MemoryUse>(&MA)) {
650 if (
BB == OldBB && firstInBB(OldPt,
Insn))
656 if (firstInBB(
Insn, NewPt))
669 int &NBBsOnAllPaths) {
671 if (NBBsOnAllPaths == 0)
681 if ((
BB != SrcBB) && HoistBarrier.
count(
BB))
688 int &NBBsOnAllPaths) {
693 "def does not dominate new hoisting point");
707 if (hasEHhelper(
BB, OldBB, NBBsOnAllPaths))
711 if (hasMemoryUse(NewPt,
Def,
BB))
715 if (NBBsOnAllPaths != -1)
725 int &NBBsOnAllPaths) {
741 if (hasEHhelper(
BB, SrcBB, NBBsOnAllPaths))
745 if (NBBsOnAllPaths != -1)
754 bool GVNHoist::safeToHoistLdSt(
const Instruction *NewPt,
756 GVNHoist::InsKind K,
int &NBBsOnAllPaths) {
773 if (
auto *UD = dyn_cast<MemoryUseOrDef>(
D))
774 if (!firstInBB(UD->getMemoryInst(), NewPt))
780 if (hasEHOrLoadsOnPath(NewPt, cast<MemoryDef>(U), NBBsOnAllPaths))
782 }
else if (hasEHOnPath(NewBB, OldBB, NBBsOnAllPaths))
816 if (safeToHoistScalar(
BB,
Insn->getParent(), NumBBsOnAllPaths))
819 auto *
T =
BB->getTerminator();
821 if (safeToHoistLdSt(
T,
Insn, UD, K, NumBBsOnAllPaths))
829 auto it1 = ValueBBs.
find(
BB);
830 if (it1 != ValueBBs.
end()) {
833 <<
" for pushing instructions on stack";);
834 for (std::pair<VNType, Instruction *> &
VI :
reverse(it1->second)) {
837 RenameStack[
VI.first].push_back(
VI.second);
846 auto P = CHIBBs.
find(Pred);
847 if (
P == CHIBBs.
end()) {
850 LLVM_DEBUG(
dbgs() <<
"\nLooking at CHIs in: " << Pred->getName(););
853 auto &VCHI =
P->second;
854 for (
auto It = VCHI.begin(),
E = VCHI.end(); It !=
E;) {
857 auto si = RenameStack.
find(
C.VN);
861 if (si != RenameStack.
end() && si->second.size() &&
864 C.I = si->second.pop_back_val();
866 <<
"\nCHI Inserted in BB: " <<
C.Dest->getName() << *
C.I
867 <<
", VN: " <<
C.VN.first <<
", " <<
C.VN.second);
877 void GVNHoist::findHoistableCandidates(
OutValuesType &CHIBBs,
891 auto TI =
BB->getTerminator();
892 auto B = CHIs.begin();
895 auto PrevIt = CHIs.begin();
896 while (PrevIt != PHIIt) {
906 if (valueAnticipable(
make_range(Safe.begin(), Safe.end()), TI)) {
916 [PrevIt](
CHIArg &A) { return A != *PrevIt; });
921 bool GVNHoist::allOperandsAvailable(
const Instruction *
I,
923 for (
const Use &
Op :
I->operands())
924 if (
const auto *Inst = dyn_cast<Instruction>(&
Op))
925 if (!DT->
dominates(Inst->getParent(), HoistPt))
931 bool GVNHoist::allGepOperandsAvailable(
const Instruction *
I,
933 for (
const Use &
Op :
I->operands())
934 if (
const auto *Inst = dyn_cast<Instruction>(&
Op))
935 if (!DT->
dominates(Inst->getParent(), HoistPt)) {
937 dyn_cast<GetElementPtrInst>(Inst)) {
938 if (!allGepOperandsAvailable(GepOp, HoistPt))
953 assert(allGepOperandsAvailable(Gep, HoistPt) &&
"GEP operands not available");
965 makeGepsAvailable(ClonedGep, HoistPt, InstructionsToHoist, GepOp);
977 for (
const Instruction *OtherInst : InstructionsToHoist) {
979 if (
auto *OtherLd = dyn_cast<LoadInst>(OtherInst))
980 OtherGep = cast<GetElementPtrInst>(OtherLd->getPointerOperand());
982 OtherGep = cast<GetElementPtrInst>(
992 if (
auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
993 ReplacementLoad->setAlignment(
994 std::min(ReplacementLoad->getAlign(), cast<LoadInst>(
I)->getAlign()));
996 }
else if (
auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
997 ReplacementStore->setAlignment(
998 std::min(ReplacementStore->getAlign(), cast<StoreInst>(
I)->getAlign()));
1000 }
else if (
auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
1001 ReplacementAlloca->setAlignment(
std::max(ReplacementAlloca->getAlign(),
1002 cast<AllocaInst>(
I)->getAlign()));
1003 }
else if (isa<CallInst>(Repl)) {
1014 updateAlignment(
I, Repl);
1019 MSSAUpdater->removeMemoryAccess(OldMA);
1024 I->replaceAllUsesWith(Repl);
1027 I->eraseFromParent();
1036 if (
MemoryPhi *Phi = dyn_cast<MemoryPhi>(U))
1040 auto In = Phi->incoming_values();
1042 Phi->replaceAllUsesWith(NewMemAcc);
1043 MSSAUpdater->removeMemoryAccess(Phi);
1048 unsigned GVNHoist::removeAndReplace(
const SmallVecInsn &Candidates,
1052 if (MoveAccess && NewMemAcc) {
1059 unsigned NR = rauw(Candidates, Repl, NewMemAcc);
1063 raMPHIuw(NewMemAcc);
1067 bool GVNHoist::makeGepOperandsAvailable(
1073 if (
auto *Ld = dyn_cast<LoadInst>(Repl)) {
1074 Gep = dyn_cast<GetElementPtrInst>(Ld->getPointerOperand());
1075 }
else if (
auto *St = dyn_cast<StoreInst>(Repl)) {
1076 Gep = dyn_cast<GetElementPtrInst>(St->getPointerOperand());
1077 Val = dyn_cast<Instruction>(St->getValueOperand());
1080 if (isa<GetElementPtrInst>(Val)) {
1082 if (!allGepOperandsAvailable(Val, HoistPt))
1090 if (!Gep || !allGepOperandsAvailable(Gep, HoistPt))
1093 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Gep);
1095 if (Val && isa<GetElementPtrInst>(Val))
1096 makeGepsAvailable(Repl, HoistPt, InstructionsToHoist, Val);
1102 unsigned NI = 0,
NL = 0, NS = 0,
NC = 0, NR = 0;
1110 if (
I->getParent() == DestBB)
1114 if (!Repl || firstInBB(
I, Repl))
1119 bool MoveAccess =
true;
1122 assert(allOperandsAvailable(Repl, DestBB) &&
1123 "instruction depends on operands that are not available");
1128 Repl = InstructionsToHoist.front();
1133 if (!allOperandsAvailable(Repl, DestBB)) {
1140 if (!makeGepOperandsAvailable(Repl, DestBB, InstructionsToHoist))
1149 DFSNumber[Repl] = DFSNumber[
Last]++;
1154 NR += removeAndReplace(InstructionsToHoist, Repl, DestBB, MoveAccess);
1156 if (isa<LoadInst>(Repl))
1158 else if (isa<StoreInst>(Repl))
1160 else if (isa<CallInst>(Repl))
1169 NumHoisted +=
NL + NS +
NC + NI;
1171 NumLoadsHoisted +=
NL;
1172 NumStoresHoisted += NS;
1173 NumCallsHoisted +=
NC;
1174 return {NI,
NL +
NC + NS};
1177 std::pair<unsigned, unsigned> GVNHoist::hoistExpressions(
Function &
F) {
1183 int InstructionNb = 0;
1197 if (
I1.isTerminator())
1200 if (
auto *Load = dyn_cast<LoadInst>(&
I1))
1202 else if (
auto *Store = dyn_cast<StoreInst>(&
I1))
1203 SI.insert(Store, VN);
1204 else if (
auto *Call = dyn_cast<CallInst>(&
I1)) {
1205 if (
auto *
Intr = dyn_cast<IntrinsicInst>(Call)) {
1206 if (isa<DbgInfoIntrinsic>(
Intr) ||
1207 Intr->getIntrinsicID() == Intrinsic::assume ||
1208 Intr->getIntrinsicID() == Intrinsic::sideeffect)
1211 if (
Call->mayHaveSideEffects())
1214 if (
Call->isConvergent())
1218 }
else if (HoistingGeps || !isa<GetElementPtrInst>(&
I1))
1258 "Early GVN Hoisting of Expressions",
false,
false)
A set of analyses that are preserved following a run of a transformation pass.
void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
const VNtoInsns & getVNTable() const
A manager for alias analyses.
const VNtoInsns & getLoadVNTable() const
void combineMetadata(Instruction *K, const Instruction *J, ArrayRef< unsigned > KnownIDs, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
This is an optimization pass for GlobalISel generic memory operations.
void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
INITIALIZE_PASS_BEGIN(GVNHoistLegacyPass, "gvn-hoist", "Early GVN Hoisting of Expressions", false, false) INITIALIZE_PASS_END(GVNHoistLegacyPass
const VNtoInsns & getStoreVNTable() const
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)"))
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
uint32_t lookupOrAdd(Value *V)
lookup_or_add - Returns the value number for the specified value, assigning it a new number if it did...
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...
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
GVNHoist(DominatorTree *DT, PostDominatorTree *PDT, AliasAnalysis *AA, MemoryDependenceResults *MD, MemorySSA *MSSA)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool operator==(const CHIArg &A) const
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
const VNtoInsns & getVNTable() const
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
void insert(StoreInst *Store, GVNPass::ValueTable &VN)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void insert(CallInst *Call, GVNPass::ValueTable &VN)
auto successors(MachineBasicBlock *BB)
Represents phi nodes for memory accesses.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Represents read-only accesses to memory.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An intrusive list with ownership and callbacks specified/controlled by ilist_traits,...
bool operator!=(const CHIArg &A) const
LLVM Basic Block Representation.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
idf_iterator< T > idf_begin(const T &G)
std::pair< BasicBlock *, SmallVecInsn > HoistingPointInfo
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
idf_iterator< T > idf_end(const T &G)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Legacy analysis pass which computes MemorySSA.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
(vector float) vec_cmpeq(*A, *B) C
Represent the analysis usage information of a pass.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
gvn hoist
When an instruction is found to only use loop invariant operands that is safe to hoist,...
Legacy analysis pass which computes a DominatorTree.
STATISTIC(NumFunctions, "Total number of functions")
auto predecessors(MachineBasicBlock *BB)
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
BasicBlock * getBlock() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in the same basic block, determine whether MemoryAccess A dominates MemoryA...
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.
Implements a dense probed hash-table based set.
Utility type to build an inheritance chain that makes it easy to rank overload candidates.
An instruction for storing to memory.
FunctionPass * createGVNHoistPass()
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
void preserve()
Mark an analysis as preserved.
Encapsulates MemorySSA, including all data associated with memory accesses.
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
initializer< Ty > init(const Ty &Val)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
std::pair< unsigned, uintptr_t > VNType
void dropLocation()
Drop the instruction's debug location.
iterator find(const_arg_type_t< KeyT > Val)
unsigned int rank(const Value *V) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StandardInstrumentations SI(Debug, VerifyEach)
An analysis that produces MemorySSA for a function.
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.
static void combineKnownMetadata(Instruction *ReplInst, Instruction *I)
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
void initializeGVNHoistLegacyPassPass(PassRegistry &)
SmallVectorImpl< CHIArg >::iterator CHIIt
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
static cl::opt< int > MaxHoistedThreshold("gvn-max-hoisted", cl::Hidden, cl::init(-1), cl::desc("Max number of instructions to hoist " "(default unlimited = -1)"))
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
This class holds the mapping between values and value numbers.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
An instruction for reading from memory.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
SmallVector< Instruction *, 4 > SmallVecInsn
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< df_iterator< T > > depth_first(const T &G)
void ensureOptimizedUses()
By default, uses are not optimized during MemorySSA construction.
Provides a lazy, caching interface for making common memory aliasing information queries,...
void stable_sort(R &&Range)
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs)
Drop all unknown metadata except for debug locations.
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)"))
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void insert(Instruction *I, GVNPass::ValueTable &VN)
bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
void sort(IteratorTy Start, IteratorTy End)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Class that has the common methods + fields of memory uses/defs.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Analysis pass which computes a DominatorTree.
unsigned getNumOperands() const
const VNtoInsns & getVNTable() const
typename SuperClass::iterator iterator
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
const BasicBlock * getParent() const
gvn Early GVN Hoisting of Expressions
Legacy wrapper pass to provide the GlobalsAAResult object.
A range adaptor for a pair of iterators.
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...
A container for analyses that lazily runs them and caches their results.
FunctionPass class - This class is used to implement most global optimizations.
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Analysis pass which computes a PostDominatorTree.
static bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA)
AnalysisUsage & addRequired()
bool VerifyMemorySSA
Enables verification of MemorySSA.
Value * getOperand(unsigned i) const
LLVM Value Representation.
iterator_range< user_iterator > users()
const VNtoInsns & getScalarVNTable() const
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)"))
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
Add support for conditional and other related patterns Instead of
A Use represents the edge between a Value definition and its users.
An analysis that produces MemoryDependenceResults for a function.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void insert(LoadInst *Load, GVNPass::ValueTable &VN)