15#ifndef LLVM_TRANSFORMS_SCALAR_GVN_H
16#define LLVM_TRANSFORMS_SCALAR_GVN_H
144 function_ref<StringRef(StringRef)> MapClassName2PassName);
174 std::vector<Expression> Expressions;
175 std::vector<uint32_t> ExprIdx;
185 using PhiTranslateMap =
187 PhiTranslateMap PhiTranslateTable;
191 bool IsMDEnabled =
false;
193 bool IsMSSAEnabled =
false;
209 std::pair<uint32_t, bool> assignExpNewValueNum(
Expression &Exp);
239 IsMDEnabled = MDEnabled;
243 IsMSSAEnabled = MSSAEnabled;
281 struct LeaderListNode {
282 LeaderTableEntry Entry;
283 LeaderListNode *
Next;
287 DenseMap<uint32_t, LeaderListNode> NumToLeaders;
292 const LeaderListNode *Current;
303 assert(Current &&
"Dereferenced end of leader list!");
304 Current = Current->Next;
308 return Current == Other.Current;
311 return Current != Other.Current;
317 auto I = NumToLeaders.find(
N);
318 if (
I == NumToLeaders.end()) {
320 leader_iterator(
nullptr));
324 leader_iterator(
nullptr));
333 for (
auto &[
_, HeadNode] : NumToLeaders) {
334 LeaderListNode *
N = HeadNode.Next;
336 auto *
Next =
N->Next;
337 N->~LeaderListNode();
341 NumToLeaders.clear();
342 TableAllocator.Reset();
345 LeaderMap LeaderTable;
349 DenseMap<AssertingVH<BasicBlock>, uint32_t> BlockRPONumber;
354 bool InvalidBlockRPONumbers =
true;
356 using LoadDepVect = SmallVector<NonLocalDepResult, 64>;
357 using AvailValInBlkVect = SmallVector<gvn::AvailableValueInBlock, 64>;
358 using UnavailBlkVect = SmallVector<BasicBlock *, 64>;
360 bool runImpl(Function &
F, AssumptionCache &RunAC, DominatorTree &RunDT,
361 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
362 MemoryDependenceResults *RunMD, LoopInfo &LI,
363 OptimizationRemarkEmitter *ORE,
MemorySSA *MSSA =
nullptr);
377 struct ReachingMemVal {
385 const Value *SelCond =
nullptr;
386 const Value *SelTrueAddr =
nullptr;
387 const Value *SelFalseAddr =
nullptr;
389 static ReachingMemVal getUnknown(BasicBlock *BB,
const Value *Addr,
390 Instruction *Inst =
nullptr) {
391 return {DepKind::Other, BB, Addr, Inst, -1};
394 static ReachingMemVal getDef(
const Value *Addr, Instruction *Inst) {
395 return {DepKind::Def, Inst->getParent(), Addr, Inst, -1};
398 static ReachingMemVal getClobber(
const Value *Addr, Instruction *Inst,
399 int32_t Offset = -1) {
400 return {DepKind::Clobber, Inst->getParent(), Addr, Inst, Offset};
403 static ReachingMemVal getSelect(BasicBlock *BB,
const Value *
Cond,
404 const Value *TrueAddr,
405 const Value *FalseAddr) {
406 return {DepKind::Select, BB,
nullptr,
nullptr, -1,
Cond,
407 TrueAddr, FalseAddr};
411 struct DependencyBlockInfo {
412 DependencyBlockInfo() =
delete;
413 DependencyBlockInfo(
const PHITransAddr &Addr, MemoryAccess *ClobberMA)
414 : Addr(Addr), InitialClobberMA(ClobberMA), ClobberMA(ClobberMA),
417 MemoryAccess *InitialClobberMA;
418 MemoryAccess *ClobberMA;
419 std::optional<ReachingMemVal> MemVal;
420 bool ForceUnknown : 1;
424 using DependencyBlockSet = DenseMap<BasicBlock *, DependencyBlockInfo>;
426 std::optional<GVNPass::ReachingMemVal> scanMemoryAccessesUsers(
427 const MemoryLocation &Loc,
bool IsInvariantLoad, BasicBlock *BB,
428 const SmallVectorImpl<MemoryAccess *> &ClobbersList,
MemorySSA &MSSA,
429 BatchAAResults &AA, LoadInst *L =
nullptr);
431 std::optional<GVNPass::ReachingMemVal>
432 accessMayModifyLocation(MemoryAccess *ClobberMA,
const MemoryLocation &Loc,
433 bool IsInvariantLoad, BasicBlock *BB,
MemorySSA &MSSA,
436 bool collectPredecessors(BasicBlock *BB,
const PHITransAddr &Addr,
437 MemoryAccess *ClobberMA, DependencyBlockSet &Blocks,
438 SmallVectorImpl<BasicBlock *> &Worklist);
440 void collectClobberList(SmallVectorImpl<MemoryAccess *> &Clobbers,
441 BasicBlock *BB,
const DependencyBlockInfo &StartInfo,
442 const DependencyBlockSet &Blocks,
MemorySSA &MSSA);
444 bool findReachingValuesForLoad(LoadInst *Inst,
445 SmallVectorImpl<ReachingMemVal> &
Values,
449 bool processLoad(LoadInst *L);
450 bool processMaskedLoad(IntrinsicInst *
I);
451 bool processNonLocalLoad(LoadInst *L);
452 bool processNonLocalLoad(LoadInst *L, SmallVectorImpl<ReachingMemVal> &Deps);
453 bool processAssumeIntrinsic(AssumeInst *
II);
457 std::optional<gvn::AvailableValue>
458 AnalyzeLoadAvailability(LoadInst *Load,
const ReachingMemVal &Dep,
465 std::optional<gvn::AvailableValue>
466 AnalyzeSelectAvailability(LoadInst *Load,
Value *
Cond,
Value *TrueAddr,
467 Value *FalseAddr, Instruction *From);
472 void AnalyzeLoadAvailability(LoadInst *Load,
473 SmallVectorImpl<ReachingMemVal> &Deps,
474 AvailValInBlkVect &ValuesPerBlock,
475 UnavailBlkVect &UnavailableBlocks);
479 LoadInst *findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
482 bool PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
483 UnavailBlkVect &UnavailableBlocks);
488 bool performLoopLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
489 UnavailBlkVect &UnavailableBlocks);
493 void eliminatePartiallyRedundantLoad(
494 LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
495 MapVector<BasicBlock *, Value *> &AvailableLoads,
496 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad);
499 bool processInstruction(Instruction *
I);
500 bool processBlock(BasicBlock *BB);
501 void dump(DenseMap<uint32_t, Value *> &Map)
const;
502 bool iterateOnFunction(Function &
F);
503 bool performPRE(Function &
F);
504 bool performScalarPRE(Instruction *
I);
505 bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
506 BasicBlock *Curr,
unsigned int ValNo);
507 Value *findLeader(
const BasicBlock *BB, uint32_t Num);
508 void cleanupGlobalSets();
509 void removeInstruction(Instruction *
I);
510 void verifyRemoved(
const Instruction *
I)
const;
511 bool splitCriticalEdges();
512 BasicBlock *splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ);
515 const std::variant<BasicBlockEdge, Instruction *> &Root);
516 bool processFoldableCondBr(CondBrInst *BI);
517 void addDeadBlock(BasicBlock *BB);
518 void assignValNumForDeadCode();
519 void assignBlockRPONumber(Function &
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis false
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_LIBRARY_VISIBILITY_NAMESPACE
This file defines the DenseMap class.
early cse Early CSE w MemorySSA
This header defines various interfaces for pass management in LLVM.
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
ppc ctr loops PowerPC CTR Loops Verify
const SmallVectorImpl< MachineOperand > & Cond
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
Value handle that asserts if the Value is deleted.
This represents the llvm.assume intrinsic.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Conditional Branch instruction.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Context-sensitive CaptureAnalysis provider, which computes and caches the earliest common dominator c...
FunctionPass class - This class is used to implement most global optimizations.
const LeaderTableEntry value_type
std::forward_iterator_tag iterator_category
bool operator==(const leader_iterator &Other) const
bool operator!=(const leader_iterator &Other) const
leader_iterator(const LeaderListNode *C)
leader_iterator & operator++()
std::ptrdiff_t difference_type
reference operator*() const
This class holds the mapping between values and value numbers.
void setMemDep(MemoryDependenceResults *M, bool MDEnabled=true)
LLVM_ABI ValueTable(ValueTable &&Arg)
void setMemorySSA(MemorySSA *M, bool MSSAEnabled=false)
LLVM_ABI uint32_t lookupPtrToInt(Value *Ptr, Type *Ty)
Returns the value number of ptrtoint Ptr to \Ty.
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
Returns the value number of the given comparison, assigning it a new number if it did not have one be...
uint32_t getNextUnusedValueNumber()
LLVM_ABI uint32_t lookup(Value *V, bool Verify=true) const
Returns the value number of the specified value.
LLVM_ABI ValueTable & operator=(const ValueTable &Arg)
void setAliasAnalysis(AAResults *A)
LLVM_ABI void add(Value *V, uint32_t Num)
add - Insert a value into the table with a specified value number.
LLVM_ABI void clear()
Remove all entries from the ValueTable.
LLVM_ABI bool exists(Value *V) const
Returns true if a value number exists for the specified value.
LLVM_ABI ValueTable(const ValueTable &Arg)
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
AAResults * getAliasAnalysis() const
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock, uint32_t Num, GVNPass &GVN)
Wrap phiTranslateImpl to provide caching functionality.
void setDomTree(DominatorTree *D)
LLVM_ABI void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock)
Erase stale entry from phiTranslate cache so phiTranslate can be computed again.
LLVM_ABI void erase(Value *V)
Remove a value from the value numbering.
LLVM_ABI void verifyRemoved(const Value *) const
verifyRemoved - Verify that the value is removed from all internal data structures.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
LLVM_ABI void salvageAndRemoveInstruction(Instruction *I)
This removes the specified instruction from our various maps and marks it for deletion.
AAResults * getAliasAnalysis() const
LLVM_ABI bool isLoadPREEnabled() const
GVNPass(GVNOptions Options={})
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI bool isMemorySSAEnabled() const
DominatorTree & getDominatorTree() const
LLVM_ABI bool isLoadInLoopPREEnabled() const
LLVM_ABI bool isScalarPREEnabled() const
LLVM_ABI bool isLoadPRESplitBackedgeEnabled() const
LLVM_ABI bool isMemDepEnabled() const
MemoryDependenceResults & getMemDep() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This class allows to keep track on instructions with implicit control flow.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
A memory dependence query can return one of three different answers.
Provides a lazy, caching interface for making common memory aliasing information queries,...
Representation for a specific memory location.
Encapsulates MemorySSA, including all data associated with memory accesses.
This is a result from a NonLocal dependence query.
A set of analyses that are preserved following a run of a transformation pass.
A vector that has set insertion semantics.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
A range adaptor for a pair of iterators.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
A private "module" namespace for types and utilities used by GVN.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
RelativeUniformCounterPtr Values
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
LLVM_ABI FunctionPass * createGVNPass()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
An information struct used to provide DenseMap with the various necessary components for a given valu...
A simple and fast domtree-based GVN pass to hoist common expressions from sibling branches.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
A set of parameters to control various transforms performed by GVN pass.
GVNOptions & setLoadPRE(bool LoadPRE)
Enables or disables PRE of loads in GVN.
std::optional< bool > AllowLoadPRESplitBackedge
std::optional< bool > AllowScalarPRE
GVNOptions & setLoadInLoopPRE(bool LoadInLoopPRE)
std::optional< bool > AllowLoadInLoopPRE
std::optional< bool > AllowMemDep
GVNOptions & setMemDep(bool MemDep)
Enables or disables use of MemDepAnalysis.
GVNOptions & setScalarPRE(bool ScalarPRE)
Enables or disables PRE of scalars in GVN.
std::optional< bool > AllowLoadPRE
GVNOptions & setLoadPRESplitBackedge(bool LoadPRESplitBackedge)
Enables or disables PRE of loads in GVN.
std::optional< bool > AllowMemorySSA
GVNOptions & setMemorySSA(bool MemSSA)
Enables or disables use of MemorySSA.
LeaderTableEntry(Value *V, const BasicBlock *BB)
Uses an "inverted" value numbering to decide the similarity of expressions and sinks similar expressi...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
A CRTP mix-in for passes that can be skipped.
Represents an AvailableValue which can be rematerialized at the end of the associated BasicBlock.
Represents a particular available value that we know how to materialize.