73 #ifndef LLVM_ANALYSIS_MEMORYSSA_H 74 #define LLVM_ANALYSIS_MEMORYSSA_H 111 class MemorySSAWalker;
115 namespace MSSAHelpers {
137 public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>,
138 public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>> {
148 void *
operator new(
size_t) =
delete;
154 return ID == MemoryUseVal || ID == MemoryPhiVal || ID == MemoryDefVal;
177 return this->AllAccessType::getIterator();
180 return this->AllAccessType::getIterator();
183 return this->AllAccessType::getReverseIterator();
186 return this->AllAccessType::getReverseIterator();
189 return this->DefsOnlyType::getIterator();
192 return this->DefsOnlyType::getIterator();
195 return this->DefsOnlyType::getReverseIterator();
198 return this->DefsOnlyType::getReverseIterator();
214 inline unsigned getID()
const;
218 :
DerivedUser(
Type::getVoidTy(C), Vty, nullptr, NumOperands, DeleteValue),
247 void *
operator new(
size_t) =
delete;
263 inline bool isOptimized()
const;
270 return OptimizedAccessAlias;
276 inline void resetOptimized();
284 unsigned NumOperands)
286 MemoryInstruction(MI), OptimizedAccessAlias(
MayAlias) {
287 setDefiningAccess(DMA);
294 OptimizedAccessAlias = AR;
304 setOptimizedAccessType(AR);
326 void *
operator new(
size_t s) {
return User::operator
new(s, 1); }
335 OptimizedID = DMA->
getID();
340 return getDefiningAccess() && OptimizedID == getDefiningAccess()->getID();
344 return getDefiningAccess();
381 : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB,
386 void *
operator new(
size_t s) {
return User::operator
new(s, 2); }
394 OptimizedID = MA->
getID();
398 return cast_or_null<MemoryAccess>(getOperand(1));
402 return getOptimized() && OptimizedID == getOptimized()->getID();
407 setOperand(1,
nullptr);
428 if (
auto *MU = dyn_cast<MemoryUse>(MUD))
434 if (
auto *MU = dyn_cast<MemoryUse>(MUD))
440 if (
const auto *MU = dyn_cast<MemoryUse>(MUD))
481 void *
operator new(
size_t s) {
return User::operator
new(s); }
489 ReservedSpace(NumPreds) {
490 allocHungoffUses(ReservedSpace);
499 auto *
Ref =
reinterpret_cast<Use::UserRef *
>(op_begin() + ReservedSpace);
505 reinterpret_cast<const Use::UserRef *
>(op_begin() + ReservedSpace);
512 return block_begin() + getNumOperands();
516 return make_range(block_begin(), block_end());
520 return make_range(block_begin(), block_end());
533 assert(V &&
"PHI node got a null value!");
546 assert(
this == U.
getUser() &&
"Iterator doesn't point to PHI's Uses?");
547 return getIncomingBlock(
unsigned(&U - op_begin()));
553 return getIncomingBlock(I.getUse());
557 assert(BB &&
"PHI node got a null basic block!");
558 block_begin()[
I] = BB;
563 if (getNumOperands() == ReservedSpace)
566 setNumHungOffUseOperands(getNumOperands() + 1);
567 setIncomingValue(getNumOperands() - 1, V);
568 setIncomingBlock(getNumOperands() - 1, BB);
574 for (
unsigned I = 0,
E = getNumOperands();
I !=
E; ++
I)
575 if (block_begin()[
I] == BB)
581 int Idx = getBasicBlockIndex(BB);
582 assert(Idx >= 0 &&
"Invalid basic block argument!");
583 return getIncomingValue(Idx);
588 unsigned E = getNumOperands();
589 assert(I < E &&
"Cannot remove out of bounds Phi entry.");
592 assert(E >= 2 &&
"Cannot only remove incoming values in MemoryPhis with " 593 "at least 2 values.");
594 setIncomingValue(I, getIncomingValue(E - 1));
595 setIncomingBlock(I, block_begin()[E - 1]);
596 setOperand(E - 1,
nullptr);
597 block_begin()[E - 1] =
nullptr;
598 setNumHungOffUseOperands(getNumOperands() - 1);
604 for (
unsigned I = 0,
E = getNumOperands();
I !=
E; ++
I)
605 if (Pred(getIncomingValue(
I), getIncomingBlock(
I))) {
606 unorderedDeleteIncoming(
I);
607 E = getNumOperands();
610 assert(getNumOperands() >= 1 &&
611 "Cannot remove all incoming blocks in a MemoryPhi.");
616 unorderedDeleteIncomingIf(
623 unorderedDeleteIncomingIf(
648 unsigned ReservedSpace;
652 void growOperands() {
653 unsigned E = getNumOperands();
655 ReservedSpace =
std::max(E + E / 2, 2u);
656 growHungoffUses(ReservedSpace,
true);
663 assert((isa<MemoryDef>(
this) || isa<MemoryPhi>(
this)) &&
664 "only memory defs and phis have ids");
665 if (
const auto *MD = dyn_cast<MemoryDef>(
this))
667 return cast<MemoryPhi>(
this)->
getID();
671 if (
const auto *MD = dyn_cast<MemoryDef>(
this))
672 return MD->isOptimized();
673 return cast<MemoryUse>(
this)->isOptimized();
677 if (
const auto *MD = dyn_cast<MemoryDef>(
this))
678 return MD->getOptimized();
679 return cast<MemoryUse>(
this)->getOptimized();
683 if (
auto *MD = dyn_cast<MemoryDef>(
this))
684 MD->setOptimized(MA);
686 cast<MemoryUse>(
this)->setOptimized(MA);
690 if (
auto *MD = dyn_cast<MemoryDef>(
this))
691 MD->resetOptimized();
693 cast<MemoryUse>(
this)->resetOptimized();
714 return cast_or_null<MemoryUseOrDef>(ValueToMemoryAccess.lookup(I));
718 return cast_or_null<MemoryPhi>(ValueToMemoryAccess.lookup(cast<Value>(BB)));
732 return MA == LiveOnEntryDef.get();
736 return LiveOnEntryDef.get();
752 return getWritableBlockAccesses(BB);
760 return getWritableBlockDefs(BB);
777 void verifyMemorySSA()
const;
780 void checkClobberSanityAccess(
const MemoryAccess *MA)
const;
793 void verifyDomination(
Function &
F)
const;
795 void verifyDominationNumbers(
const Function &
F)
const;
796 void verifyClobberSanity(
const Function &
F)
const;
800 auto It = PerBlockAccesses.find(BB);
801 return It == PerBlockAccesses.end() ? nullptr : It->second.get();
806 auto It = PerBlockDefs.find(BB);
807 return It == PerBlockDefs.
end() ? nullptr : It->second.get();
820 renamePass(DT->getNode(BB), IncomingVal, Visited,
true,
true);
824 void removeFromLists(
MemoryAccess *,
bool ShouldDelete =
true);
828 AccessList::iterator);
839 void buildMemorySSA();
850 void markUnreachableAsLiveOnEntry(
BasicBlock *BB);
861 bool SkipVisited =
false,
bool RenameAllUses =
false);
880 std::unique_ptr<MemoryAccess, ValueDeleter> LiveOnEntryDef;
889 std::unique_ptr<ClobberWalkerBase> WalkerBase;
890 std::unique_ptr<CachingWalker> Walker;
891 std::unique_ptr<SkipSelfWalker> SkipWalker;
902 static bool defClobbersUseOrDef(MemoryDef *MD,
const MemoryUseOrDef *MU,
930 Result(std::unique_ptr<MemorySSA> &&MSSA) : MSSA(
std::move(MSSA)) {}
934 std::unique_ptr<MemorySSA>
MSSA;
963 void releaseMemory()
override;
969 void verifyAnalysis()
const override;
973 std::unique_ptr<MemorySSA> MSSA;
1018 assert(MA &&
"Handed an instruction that MemorySSA doesn't recognize?");
1019 return getClobberingMemoryAccess(MA);
1076 std::forward_iterator_tag, T, ptrdiff_t, T *,
1078 using BaseT =
typename memoryaccess_def_iterator_base::iterator_facade_base;
1085 return Access == Other.Access && (!Access || ArgNo == Other.ArgNo);
1095 MemoryPhi *MP =
dyn_cast<MemoryPhi>(Access);
1096 assert(MP &&
"Tried to get phi arg block when not iterating over a PHI");
1101 assert(Access &&
"Tried to access past the end of our iterator");
1104 if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Access))
1105 return MP->getIncomingValue(ArgNo);
1106 return cast<MemoryUseOrDef>(Access)->getDefiningAccess();
1109 using BaseT::operator++;
1111 assert(Access &&
"Hit end of iterator");
1112 if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Access)) {
1113 if (++ArgNo >= MP->getNumIncomingValues()) {
1124 T *Access =
nullptr;
1174 std::forward_iterator_tag,
1175 const MemoryAccessPair> {
1176 using BaseT = upward_defs_iterator::iterator_facade_base;
1181 OriginalAccess(Info.
first) {
1182 CurrentPair.first =
nullptr;
1184 WalkingPhi = Info.first && isa<MemoryPhi>(Info.first);
1185 fillInCurrentPair();
1191 return DefIterator == Other.DefIterator;
1195 assert(DefIterator != OriginalAccess->defs_end() &&
1196 "Tried to access past the end of our iterator");
1200 using BaseT::operator++;
1202 assert(DefIterator != OriginalAccess->defs_end() &&
1203 "Tried to access past the end of the iterator");
1205 if (DefIterator != OriginalAccess->defs_end())
1206 fillInCurrentPair();
1213 void fillInCurrentPair() {
1214 CurrentPair.first = *DefIterator;
1215 if (WalkingPhi && Location.Ptr) {
1217 const_cast<Value *>(Location.Ptr),
1218 OriginalAccess->getBlock()->getModule()->getDataLayout(),
nullptr);
1219 if (!Translator.PHITranslateValue(OriginalAccess->getBlock(),
1220 DefIterator.getPhiArgBlock(),
nullptr,
1222 if (Translator.getAddr() != Location.Ptr) {
1223 CurrentPair.second = Location.getWithNewPtr(Translator.getAddr());
1227 CurrentPair.second = Location;
1234 bool WalkingPhi =
false;
1261 template <
class T,
bool UseOptimizedChain = false>
1264 std::forward_iterator_tag, MemoryAccess *> {
1272 if (
auto *MUD = dyn_cast<MemoryUseOrDef>(MA)) {
1273 if (UseOptimizedChain && MUD->isOptimized())
1274 MA = MUD->getOptimized();
1276 MA = MUD->getDefiningAccess();
1293 #ifdef EXPENSIVE_CHECKS 1295 "UpTo isn't in the def chain!");
1308 #endif // LLVM_ANALYSIS_MEMORYSSA_H
AccessList * getWritableBlockAccesses(const BasicBlock *BB) const
memoryaccess_def_iterator & operator++()
BasicBlock * getIncomingBlock(MemoryAccess::const_user_iterator I) const
Return incoming basic block corresponding to value use iterator.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
unsigned getValueID() const
Return an ID for the concrete type of this object.
virtual void verify(const MemorySSA *MSSA)
void unorderedDeleteIncomingValue(const MemoryAccess *MA)
This class represents lattice values for constants.
void unorderedDeleteIncomingIf(Fn &&Pred)
Result(std::unique_ptr< MemorySSA > &&MSSA)
AllAccessType::self_iterator getIterator()
Get the iterators for the all access list and the defs only list We default to the all access list...
BasicBlock * getIncomingBlock(const Use &U) const
Return incoming basic block corresponding to an operand of the PHI.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
MemorySSAPrinterPass(raw_ostream &OS)
A Module instance is used to store all the information related to an LLVM module. ...
const MemorySSA & getMSSA() const
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
BasicBlock *const * const_block_iterator
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
MemoryAccess * getOptimized() const
Extension point for the Value hierarchy.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
BaseT::iterator::reference operator*() const
void setOptimized(MemoryAccess *)
void deleteValue()
Delete a pointer to a generic Value.
BasicBlock * getPhiArgBlock() const
memoryaccess_def_iterator defs_begin()
This iterator walks over all of the defs in a given MemoryAccess.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
void(*)(DerivedUser *) DeleteValueTy
This defines the Use class.
AllAccessType::const_self_iterator getIterator() const
DefsOnlyType::self_iterator getDefsIterator()
void setIncomingValue(unsigned I, MemoryAccess *V)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
MemoryPhi * getMemoryAccess(const BasicBlock *BB) const
Represents read-only accesses to memory.
This class is a batch walker of all MemoryUse's in the program, and points their defining access at t...
Legacy analysis pass which computes MemorySSA.
void resetOptimized()
Reset the ID of what this MemoryUse was optimized to, causing it to be rewalked by the walker if nece...
void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal, SmallPtrSetImpl< BasicBlock *> &Visited)
block_iterator block_begin()
A MemorySSAWalker that does AA walks to disambiguate accesses.
A Use represents the edge between a Value definition and its users.
Encapsulates MemorySSA, including all data associated with memory accesses.
The access may reference the value stored in memory.
const DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
const_block_iterator block_end() const
Walks the defining accesses of MemoryDefs.
def_chain_iterator & operator++()
BaseT::iterator::pointer operator*() const
static bool classof(const Value *MA)
iterator_range< block_iterator > blocks()
A simple intrusive list implementation.
#define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS)
Macro for generating out-of-class operand accessor definitions.
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
static ChildIteratorType child_end(NodeRef N)
static int getID(struct InternalInstruction *insn, const void *miiArg)
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
MemoryAccess * getOptimized() const
AllAccessType::const_reverse_self_iterator getReverseIterator() const
upward_defs_iterator upward_defs_end()
std::unique_ptr< MemorySSA > MSSA
void unorderedDeleteIncoming(unsigned I)
A CRTP mix-in to automatically provide informational APIs needed for passes.
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()
Analysis containing CSE Info
MemoryAccess * getIncomingValue(unsigned I) const
Return incoming value number x.
const_block_iterator block_begin() const
An assembly annotator class to print Memory SSA information in comments.
Use delete by default for iplist and ilist.
static bool runOnFunction(Function &F, bool PostInlining)
static Use * op_end(MemoryUseOrDef *MUD)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
DefsOnlyType::const_reverse_self_iterator getReverseDefsIterator() const
AllAccessType::reverse_self_iterator getReverseIterator()
LLVM Basic Block Representation.
PointerIntPair - This class implements a pair of a pointer and small integer.
PHITransAddr - An address value which tracks and handles phi translation.
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.
const_op_range incoming_values() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
upward_defs_iterator & operator++()
void addIncoming(MemoryAccess *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
early cse Early CSE w MemorySSA
A CRTP mix-in that provides informational APIs needed for analysis passes.
static unsigned getIncomingValueNumForOperand(unsigned I)
void setIncomingBlock(unsigned I, BasicBlock *BB)
upward_defs_iterator(const MemoryAccessPair &Info)
InsertionPlace
Used in various insertion functions to specify whether we are talking about the beginning or end of a...
Represent the analysis usage information of a pass.
iterator_range< def_chain_iterator< T, true > > optimized_def_chain(T MA)
void print(raw_ostream &OS) const
Printer pass for MemorySSA.
static unsigned getOperandNumForIncomingValue(unsigned I)
FunctionPass class - This class is used to implement most global optimizations.
static bool classof(const Value *MA)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
MemoryAccess::iterator ChildIteratorType
static unsigned operands(const MemoryUseOrDef *MUD)
BasicBlock * getPhiArgBlock() const
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.
Provide an iterator that walks defs, giving both the memory access, and the current pointer location...
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
An intrusive list with ownership and callbacks specified/controlled by ilist_traits, only with API safe for polymorphic types.
MemoryAccess * getOptimized() const
A MemorySSAWalker that does no alias queries, or anything else.
std::pair< const MemoryAccess *, MemoryLocation > ConstMemoryAccessPair
static void deleteNode(MemoryAccess *MA)
bool operator==(const memoryaccess_def_iterator_base &Other) const
The two locations may or may not alias. This is the least precise result.
Representation for a specific memory location.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void setDefiningAccess(MemoryAccess *DMA, bool Optimized=false, Optional< AliasResult > AR=MayAlias)
Iterator for intrusive lists based on ilist_node.
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.
BasicBlock * getBlock() const
void unorderedDeleteIncomingBlock(const BasicBlock *BB)
MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty, DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB, unsigned NumOperands)
MemoryAccess * getLiveOnEntryDef() const
Verifier pass for MemorySSA.
A range adaptor for a pair of iterators.
MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds=0)
static Use * op_begin(MemoryUseOrDef *MUD)
Class that has the common methods + fields of memory uses/defs.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
iterator_range< const_block_iterator > blocks() const
user_iterator_impl< const User > const_user_iterator
DefsOnlyType::const_self_iterator getDefsIterator() const
void setOptimizedAccessType(Optional< AliasResult > AR)
iterator_range< def_chain_iterator< T > > def_chain(T MA, MemoryAccess *UpTo=nullptr)
memoryaccess_def_iterator_base< MemoryAccess > memoryaccess_def_iterator
block_iterator block_end()
bool operator==(const def_chain_iterator &O) const
This file provides utility analysis objects describing memory locations.
user_iterator_impl< User > user_iterator
MemoryAccess * getIncomingValueForBlock(const BasicBlock *BB) const
Compile-time customization of User operands.
MemoryAccess(LLVMContext &C, unsigned Vty, DeleteValueTy DeleteValue, BasicBlock *BB, unsigned NumOperands)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
Optional< AliasResult > getOptimizedAccessType() const
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)
static bool classof(const Value *MA)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
void setOptimized(MemoryAccess *MA)
static NodeRef getEntryNode(NodeRef N)
LLVM Value Representation.
MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB, unsigned Ver)
DefsOnlyType::reverse_self_iterator getReverseDefsIterator()
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.
unsigned getID() const
Used for debugging and tracking things about MemoryAccesses.
memoryaccess_def_iterator_base(T *Start)
This class implements an extremely fast bulk output stream that can only output to a stream...
const_user_iterator const_iterator
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.
void setBlock(BasicBlock *BB)
Used by MemorySSA to change the block of a MemoryAccess when it is moved.
MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
static bool classof(const Value *V)
iterator_range< upward_defs_iterator > upward_defs(const MemoryAccessPair &Pair)
Represents phi nodes for memory accesses.
static ChildIteratorType child_end(NodeRef N)
DefsList * getWritableBlockDefs(const BasicBlock *BB) const
user_iterator iterator
The user iterators for a memory access.
memoryaccess_def_iterator_base< const MemoryAccess > const_memoryaccess_def_iterator
bool operator==(const upward_defs_iterator &Other) const
A special type used by analysis passes to provide an address that identifies that particular analysis...
void setOptimized(MemoryAccess *DMA)
std::pair< MemoryAccess *, MemoryLocation > MemoryAccessPair
void allocHungoffUses(unsigned N)
this is more complicated than the generic User::allocHungoffUses, because we have to allocate Uses fo...