72 #ifndef LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
73 #define LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
127 void *
operator new(size_t,
unsigned) =
delete;
128 void *
operator new(size_t) =
delete;
136 return ID == MemoryUseVal || ID == MemoryPhiVal || ID == MemoryDefVal;
144 virtual void dump()
const;
167 virtual unsigned getID()
const = 0;
170 unsigned NumOperands)
171 :
User(
Type::getVoidTy(C), Vty, nullptr, NumOperands), Block(BB) {}
192 void *
operator new(size_t,
unsigned) =
delete;
193 void *
operator new(size_t) =
delete;
235 void *
operator new(size_t,
unsigned) =
delete;
241 void *
operator new(
size_t s) {
return User::operator
new(s, 1); }
244 : MemoryUseOrDef(C, DMA, MemoryUseVal, MI, BB), OptimizedID(0) {}
254 OptimizedID = DMA->
getID();
258 return getDefiningAccess() && OptimizedID == getDefiningAccess()->getID();
273 unsigned int OptimizedID;
290 void *
operator new(size_t,
unsigned) =
delete;
296 void *
operator new(
size_t s) {
return User::operator
new(s, 1); }
300 : MemoryUseOrDef(C, DMA, MemoryDefVal, MI, BB),
ID(Ver) {}
312 unsigned getID()
const override {
return ID; }
355 void *
operator new(size_t,
unsigned) =
delete;
357 void *
operator new(
size_t s) {
return User::operator
new(s); }
364 : MemoryAccess(C, MemoryPhiVal, BB, 0),
ID(Ver), ReservedSpace(NumPreds) {
365 allocHungoffUses(ReservedSpace);
374 auto *Ref =
reinterpret_cast<Use::UserRef *
>(op_begin() + ReservedSpace);
375 return reinterpret_cast<block_iterator
>(Ref + 1);
380 reinterpret_cast<const Use::UserRef *
>(op_begin() + ReservedSpace);
381 return reinterpret_cast<const_block_iterator
>(Ref + 1);
384 block_iterator
block_end() {
return block_begin() + getNumOperands(); }
387 return block_begin() + getNumOperands();
391 return make_range(block_begin(), block_end());
395 return make_range(block_begin(), block_end());
408 assert(V &&
"PHI node got a null value!");
420 assert(
this == U.
getUser() &&
"Iterator doesn't point to PHI's Uses?");
421 return getIncomingBlock(
unsigned(&U - op_begin()));
427 return getIncomingBlock(I.getUse());
431 assert(BB &&
"PHI node got a null basic block!");
432 block_begin()[
I] = BB;
437 if (getNumOperands() == ReservedSpace)
440 setNumHungOffUseOperands(getNumOperands() + 1);
441 setIncomingValue(getNumOperands() - 1, V);
442 setIncomingBlock(getNumOperands() - 1, BB);
448 for (
unsigned I = 0,
E = getNumOperands();
I !=
E; ++
I)
449 if (block_begin()[
I] == BB)
455 int Idx = getBasicBlockIndex(BB);
456 assert(Idx >= 0 &&
"Invalid basic block argument!");
457 return getIncomingValue(Idx);
481 unsigned ReservedSpace;
485 void growOperands() {
486 unsigned E = getNumOperands();
488 ReservedSpace = std::max(E + E / 2, 2u);
489 growHungoffUses(ReservedSpace,
true);
505 MemorySSAWalker *getWalker();
525 return MA == LiveOnEntryDef.get();
529 return LiveOnEntryDef.get();
538 return getWritableBlockAccesses(BB);
563 InsertionPlace Point);
612 void verifyMemorySSA()
const;
619 void verifyDomination(
Function &
F)
const;
624 auto It = PerBlockAccesses.find(BB);
625 return It == PerBlockAccesses.end() ?
nullptr : It->second.get();
632 CachingWalker *getWalkerImpl();
633 void buildMemorySSA();
642 void markUnreachableAsLiveOnEntry(
BasicBlock *BB);
654 AccessList *getOrCreateAccessList(
const BasicBlock *);
663 AccessMap PerBlockAccesses;
664 std::unique_ptr<MemoryAccess> LiveOnEntryDef;
673 std::unique_ptr<CachingWalker> Walker;
702 std::unique_ptr<MemorySSA>
MSSA;
739 std::unique_ptr<MemorySSA> MSSA;
784 assert(MA &&
"Handed an instruction that MemorySSA doesn't recognize?");
841 std::forward_iterator_tag, T, ptrdiff_t, T *,
843 using BaseT =
typename memoryaccess_def_iterator_base::iterator_facade_base;
849 return Access == Other.Access && (!Access || ArgNo == Other.ArgNo);
860 assert(MP &&
"Tried to get phi arg block when not iterating over a PHI");
864 assert(Access &&
"Tried to access past the end of our iterator");
867 if (
MemoryPhi *MP = dyn_cast<MemoryPhi>(Access))
868 return MP->getIncomingValue(ArgNo);
869 return cast<MemoryUseOrDef>(Access)->getDefiningAccess();
871 using BaseT::operator++;
873 assert(Access &&
"Hit end of iterator");
874 if (
MemoryPhi *MP = dyn_cast<MemoryPhi>(Access)) {
875 if (++ArgNo >= MP->getNumIncomingValues()) {
936 std::forward_iterator_tag,
937 const MemoryAccessPair> {
938 using BaseT = upward_defs_iterator::iterator_facade_base;
942 : DefIterator(Info.first), Location(Info.second),
943 OriginalAccess(Info.first) {
944 CurrentPair.first =
nullptr;
946 WalkingPhi = Info.first && isa<MemoryPhi>(Info.first);
951 : DefIterator(), Location(), OriginalAccess(), WalkingPhi(
false) {
952 CurrentPair.first =
nullptr;
956 return DefIterator == Other.DefIterator;
961 "Tried to access past the end of our iterator");
965 using BaseT::operator++;
968 "Tried to access past the end of the iterator");
970 if (DefIterator != OriginalAccess->
defs_end())
978 void fillInCurrentPair() {
979 CurrentPair.first = *DefIterator;
980 if (WalkingPhi && Location.
Ptr) {
982 const_cast<Value *>(Location.
Ptr),
984 if (!Translator.PHITranslateValue(OriginalAccess->
getBlock(),
987 if (Translator.getAddr() != Location.
Ptr) {
988 CurrentPair.second = Location.
getWithNewPtr(Translator.getAddr());
992 CurrentPair.second = Location;
997 MemoryLocation Location;
998 MemoryAccess *OriginalAccess;
1014 #endif // LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
static bool classof(const MemoryUseOrDef *)
memoryaccess_def_iterator & operator++()
MemoryAccess * getClobberingMemoryAccess(MemoryAccess *) override
Does the same thing as getClobberingMemoryAccess(const Instruction *I), but takes a MemoryAccess inst...
BasicBlock *const * const_block_iterator
virtual void verify(const MemorySSA *MSSA)
Result(std::unique_ptr< MemorySSA > &&MSSA)
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
bool operator==(const memoryaccess_def_iterator_base &Other) const
MemorySSAPrinterPass(raw_ostream &OS)
A Module instance is used to store all the information related to an LLVM module. ...
void resetOptimized()
Reset the ID of what this MemoryUse was optimized to, causing it to be rewalked by the walker if nece...
Result run(Function &F, FunctionAnalysisManager &AM)
bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA)
BaseT::iterator::reference operator*() const
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
memoryaccess_def_iterator defs_begin()
This iterator walks over all of the defs in a given MemoryAccess.
const_block_iterator block_end() const
MemoryAccess(LLVMContext &C, unsigned Vty, BasicBlock *BB, unsigned NumOperands)
BasicBlock * getPhiArgBlock() const
This defines the Use class.
BasicBlock * getIncomingBlock(MemoryAccess::const_user_iterator I) const
Return incoming basic block corresponding to value use iterator.
const MemorySSA & getMSSA() const
void setIncomingValue(unsigned I, MemoryAccess *V)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
const_op_range incoming_values() const
Represents read-only accesses to memory.
static bool classof(const MemoryPhi *)
virtual void dump() const
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Legacy analysis pass which computes MemorySSA.
block_iterator block_begin()
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr it the function does no...
A Use represents the edge between a Value definition and its users.
AccessList * getWritableBlockAccesses(const BasicBlock *BB) const
Encapsulates MemorySSA, including all data associated with memory accesses.
MemoryUseOrDef * getMemoryAccess(const Instruction *) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
MemoryLocation getWithNewPtr(const Value *NewPtr) const
static bool classof(const Value *MA)
iterator_range< block_iterator > blocks()
BasicBlock * getBlock() const
user_iterator_impl< User > user_iterator
#define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS)
Macro for generating out-of-class operand accessor definitions.
static bool classof(const MemoryAccess *)
static ChildIteratorType child_end(NodeRef N)
upward_defs_iterator upward_defs_end()
std::unique_ptr< MemorySSA > MSSA
A CRTP mix-in to automatically provide informational APIs needed for passes.
Function Alias Analysis false
Base class for the actual dominator tree node.
const_block_iterator block_begin() const
bool runOnFunction(Function &) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
virtual unsigned getID() const =0
Used for debugging and tracking things about MemoryAccesses.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
This is the generic walker interface for walkers of MemorySSA.
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
op_range incoming_values()
memoryaccess_def_iterator defs_end()
unsigned getID() const final
Used for debugging and tracking things about MemoryAccesses.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty, Instruction *MI, BasicBlock *BB)
An assembly annotator class to print Memory SSA information in comments.
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
LLVM Basic Block Representation.
void setDefiningAccess(MemoryAccess *DMA, bool Optimized=false)
PointerIntPair - This class implements a pair of a pointer and small integer.
PHITransAddr - An address value which tracks and handles phi translation.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
upward_defs_iterator & operator++()
static bool classof(const MemoryUse *)
void addIncoming(MemoryAccess *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
virtual void print(raw_ostream &OS) const =0
early cse Early CSE w MemorySSA
A CRTP mix-in that provides informational APIs needed for analysis passes.
static unsigned getIncomingValueNumForOperand(unsigned I)
bool runOnFunction(Function &) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
MemorySSAWalker(MemorySSA *)
void setIncomingBlock(unsigned I, BasicBlock *BB)
upward_defs_iterator(const MemoryAccessPair &Info)
Represent the analysis usage information of a pass.
BasicBlock ** block_iterator
void setDefiningAccess(MemoryAccess *DMA)
Printer pass for MemorySSA.
unsigned getValueID() const
Return an ID for the concrete type of this object.
static const unsigned End
static bool classof(const MemoryDef *)
static unsigned getOperandNumForIncomingValue(unsigned I)
User * getUser() const
Returns the User that contains this Use.
FunctionPass class - This class is used to implement most global optimizations.
static bool classof(const Value *MA)
Value * getOperand(unsigned i) const
MemoryAccess::iterator ChildIteratorType
virtual ~MemorySSAWalker()
MemoryAccess * getIncomingValue(unsigned I) const
Return incoming value number x.
virtual void invalidateInfo(MemoryAccess *)
Given a memory access, invalidate anything this walker knows about that access.
Iterator base class used to implement const and non-const iterators over the defining accesses of a M...
#define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS)
Macro for generating in-class operand accessor declarations.
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
Provide an iterator that walks defs, giving both the memory access, and the current pointer location...
An intrusive list with ownership and callbacks specified/controlled by ilist_traits, only with API safe for polymorphic types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A MemorySSAWalker that does no alias queries, or anything else.
MemoryAccess * getLiveOnEntryDef() const
std::pair< const MemoryAccess *, MemoryLocation > ConstMemoryAccessPair
unsigned getID() const override
Used for debugging and tracking things about MemoryAccesses.
memoryaccess_def_iterator_base()
iterator_range< const_block_iterator > blocks() const
const Value * Ptr
The address of the start of the location.
Representation for a specific memory location.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
BaseT::iterator::pointer operator*() const
static bool classof(const Value *V)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static NodeRef getEntryNode(NodeRef N)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
An analysis that produces MemorySSA for a function.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
bool operator==(const upward_defs_iterator &Other) const
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
void setOperand(unsigned i, Value *Val)
Verifier pass for MemorySSA.
A range adaptor for a pair of iterators.
MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds=0)
Class that has the common methods + fields of memory uses/defs.
BasicBlock * getPhiArgBlock() const
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
user_iterator iterator
The user iterators for a memory access.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
user_iterator_impl< const User > const_user_iterator
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess)
memoryaccess_def_iterator_base< MemoryAccess > memoryaccess_def_iterator
block_iterator block_end()
This file provides utility analysis objects describing memory locations.
BasicBlock * getIncomingBlock(const Use &U) const
Return incoming basic block corresponding to an operand of the PHI.
Compile-time customization of User operands.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
MemorySSAPrinterLegacyPass()
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
static ChildIteratorType child_begin(NodeRef N)
MemoryAccess * getClobberingMemoryAccess(const Instruction *I)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
static ChildIteratorType child_begin(NodeRef N)
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
static bool classof(const Value *MA)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
static NodeRef getEntryNode(NodeRef N)
LLVM Value Representation.
unsigned getID() const override
Used for debugging and tracking things about MemoryAccesses.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB, unsigned Ver)
upward_defs_iterator upward_defs_begin(const MemoryAccessPair &Pair)
HungoffOperandTraits - determine the allocation regime of the Use array when it is not a prefix to th...
void allocHungoffUses(unsigned N, bool IsPhi=false)
Allocate the array of Uses, followed by a pointer (with bottom bit set) to the User.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
memoryaccess_def_iterator_base(T *Start)
This class implements an extremely fast bulk output stream that can only output to a stream...
FixedNumOperandTraits - determine the allocation regime of the Use array when it is a prefix to the U...
A container for analyses that lazily runs them and caches their results.
MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
static bool classof(const Value *V)
Represents phi nodes for memory accesses.
static ChildIteratorType child_end(NodeRef N)
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
memoryaccess_def_iterator_base< const MemoryAccess > const_memoryaccess_def_iterator
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
const_user_iterator const_iterator
A special type used by analysis passes to provide an address that identifies that particular analysis...
std::pair< MemoryAccess *, MemoryLocation > MemoryAccessPair
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
void allocHungoffUses(unsigned N)
this is more complicated than the generic User::allocHungoffUses, because we have to allocate Uses fo...