Go to the documentation of this file.
85 #ifndef LLVM_ANALYSIS_MEMORYSSA_H
86 #define LLVM_ANALYSIS_MEMORYSSA_H
110 template <
class GraphType>
struct GraphTraits;
116 class MemorySSAWalker;
122 namespace MSSAHelpers {
144 public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>,
145 public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>> {
155 void *
operator new(
size_t) =
delete;
161 return ID == MemoryUseVal ||
ID == MemoryPhiVal ||
ID == MemoryDefVal;
221 inline unsigned getID()
const;
254 void *
operator new(
size_t) =
delete;
292 unsigned NumOperands)
294 MemoryInstruction(
MI), OptimizedAccessAlias(
AliasResult::MayAlias) {
302 OptimizedAccessAlias = AR;
335 void *
operator new(
size_t S) {
return User::operator
new(
S, 1); }
336 void operator delete(
void *Ptr) { User::operator
delete(Ptr); }
345 OptimizedID = DMA->
getID();
399 void *
operator new(
size_t S) {
return User::operator
new(
S, 2); }
400 void operator delete(
void *Ptr) { User::operator
delete(Ptr); }
408 OptimizedID = MA->
getID();
412 return cast_or_null<MemoryAccess>(getOperand(1));
416 return getOptimized() && OptimizedID == getOptimized()->getID();
421 setOperand(1,
nullptr);
442 if (
auto *MU = dyn_cast<MemoryUse>(MUD))
448 if (
auto *MU = dyn_cast<MemoryUse>(MUD))
454 if (
const auto *MU = dyn_cast<MemoryUse>(MUD))
495 void *
operator new(
size_t S) {
return User::operator
new(
S); }
498 void operator delete(
void *Ptr) { User::operator
delete(Ptr); }
505 ReservedSpace(NumPreds) {
506 allocHungoffUses(ReservedSpace);
515 return reinterpret_cast<block_iterator>(op_begin() + ReservedSpace);
525 return block_begin() + getNumOperands();
529 return make_range(block_begin(), block_end());
533 return make_range(block_begin(), block_end());
546 assert(V &&
"PHI node got a null value!");
559 assert(
this == U.
getUser() &&
"Iterator doesn't point to PHI's Uses?");
560 return getIncomingBlock(
unsigned(&U - op_begin()));
566 return getIncomingBlock(
I.getUse());
570 assert(
BB &&
"PHI node got a null basic block!");
571 block_begin()[
I] =
BB;
576 if (getNumOperands() == ReservedSpace)
579 setNumHungOffUseOperands(getNumOperands() + 1);
580 setIncomingValue(getNumOperands() - 1, V);
581 setIncomingBlock(getNumOperands() - 1,
BB);
587 for (
unsigned I = 0,
E = getNumOperands();
I !=
E; ++
I)
588 if (block_begin()[
I] ==
BB)
594 int Idx = getBasicBlockIndex(
BB);
595 assert(Idx >= 0 &&
"Invalid basic block argument!");
596 return getIncomingValue(Idx);
601 unsigned E = getNumOperands();
602 assert(
I <
E &&
"Cannot remove out of bounds Phi entry.");
605 assert(
E >= 2 &&
"Cannot only remove incoming values in MemoryPhis with "
606 "at least 2 values.");
607 setIncomingValue(
I, getIncomingValue(
E - 1));
608 setIncomingBlock(
I, block_begin()[
E - 1]);
609 setOperand(
E - 1,
nullptr);
610 block_begin()[
E - 1] =
nullptr;
611 setNumHungOffUseOperands(getNumOperands() - 1);
617 for (
unsigned I = 0,
E = getNumOperands();
I !=
E; ++
I)
618 if (Pred(getIncomingValue(
I), getIncomingBlock(
I))) {
619 unorderedDeleteIncoming(
I);
620 E = getNumOperands();
623 assert(getNumOperands() >= 1 &&
624 "Cannot remove all incoming blocks in a MemoryPhi.");
629 unorderedDeleteIncomingIf(
636 unorderedDeleteIncomingIf(
661 unsigned ReservedSpace;
665 void growOperands() {
666 unsigned E = getNumOperands();
669 growHungoffUses(ReservedSpace,
true);
672 static void deleteMe(DerivedUser *Self);
676 assert((isa<MemoryDef>(
this) || isa<MemoryPhi>(
this)) &&
677 "only memory defs and phis have ids");
678 if (
const auto *MD = dyn_cast<MemoryDef>(
this))
680 return cast<MemoryPhi>(
this)->getID();
684 if (
const auto *MD = dyn_cast<MemoryDef>(
this))
685 return MD->isOptimized();
686 return cast<MemoryUse>(
this)->isOptimized();
690 if (
const auto *MD = dyn_cast<MemoryDef>(
this))
691 return MD->getOptimized();
692 return cast<MemoryUse>(
this)->getOptimized();
696 if (
auto *MD = dyn_cast<MemoryDef>(
this))
697 MD->setOptimized(MA);
699 cast<MemoryUse>(
this)->setOptimized(MA);
703 if (
auto *MD = dyn_cast<MemoryDef>(
this))
704 MD->resetOptimized();
706 cast<MemoryUse>(
this)->resetOptimized();
732 return cast_or_null<MemoryUseOrDef>(ValueToMemoryAccess.lookup(
I));
736 return cast_or_null<MemoryPhi>(ValueToMemoryAccess.lookup(cast<Value>(
BB)));
752 return MA == LiveOnEntryDef.get();
756 return LiveOnEntryDef.get();
772 return getWritableBlockAccesses(
BB);
780 return getWritableBlockDefs(
BB);
809 void ensureOptimizedUses();
816 void verifyOrderingDominationAndDefUses(
818 void verifyDominationNumbers(
const Function &
F)
const;
819 void verifyPrevDefInPhis(
Function &
F)
const;
823 auto It = PerBlockAccesses.find(
BB);
824 return It == PerBlockAccesses.end() ? nullptr : It->second.get();
829 auto It = PerBlockDefs.find(
BB);
830 return It == PerBlockDefs.
end() ? nullptr : It->second.get();
843 renamePass(DT->getNode(
BB), IncomingVal, Visited,
true,
true);
847 void removeFromLists(
MemoryAccess *,
bool ShouldDelete =
true);
851 AccessList::iterator);
854 bool CreationMustSucceed =
true);
857 template <
class AliasAnalysisType>
class ClobberWalkerBase;
858 template <
class AliasAnalysisType>
class CachingWalker;
859 template <
class AliasAnalysisType>
class SkipSelfWalker;
862 CachingWalker<AliasAnalysis> *getWalkerImpl();
873 template <
typename AliasAnalysisType>
881 bool SkipVisited =
false,
bool RenameAllUses =
false);
882 AccessList *getOrCreateAccessList(
const BasicBlock *);
883 DefsList *getOrCreateDefsList(
const BasicBlock *);
898 AccessMap PerBlockAccesses;
899 DefsMap PerBlockDefs;
900 std::unique_ptr<MemoryAccess, ValueDeleter> LiveOnEntryDef;
909 std::unique_ptr<ClobberWalkerBase<AliasAnalysis>> WalkerBase;
910 std::unique_ptr<CachingWalker<AliasAnalysis>> Walker;
911 std::unique_ptr<SkipSelfWalker<AliasAnalysis>> SkipWalker;
913 bool IsOptimized =
false;
962 std::unique_ptr<MemorySSA>
MSSA;
1015 std::unique_ptr<MemorySSA> MSSA;
1060 assert(MA &&
"Handed an instruction that MemorySSA doesn't recognize?");
1116 std::forward_iterator_tag, T, ptrdiff_t, T *,
1118 using BaseT =
typename memoryaccess_def_iterator_base::iterator_facade_base;
1125 return Access ==
Other.Access && (!Access || ArgNo ==
Other.ArgNo);
1135 MemoryPhi *MP = dyn_cast<MemoryPhi>(Access);
1136 assert(MP &&
"Tried to get phi arg block when not iterating over a PHI");
1141 assert(Access &&
"Tried to access past the end of our iterator");
1144 if (
const MemoryPhi *MP = dyn_cast<MemoryPhi>(Access))
1145 return MP->getIncomingValue(ArgNo);
1146 return cast<MemoryUseOrDef>(Access)->getDefiningAccess();
1149 using BaseT::operator++;
1151 assert(Access &&
"Hit end of iterator");
1152 if (
const MemoryPhi *MP = dyn_cast<MemoryPhi>(Access)) {
1153 if (++ArgNo >= MP->getNumIncomingValues()) {
1164 T *Access =
nullptr;
1214 std::forward_iterator_tag,
1215 const MemoryAccessPair> {
1216 using BaseT = upward_defs_iterator::iterator_facade_base;
1220 bool *PerformedPhiTranslation =
nullptr)
1221 : DefIterator(
Info.first), Location(
Info.second),
1222 OriginalAccess(
Info.first), DT(DT),
1223 PerformedPhiTranslation(PerformedPhiTranslation) {
1224 CurrentPair.first =
nullptr;
1226 WalkingPhi =
Info.first && isa<MemoryPhi>(
Info.first);
1227 fillInCurrentPair();
1233 return DefIterator ==
Other.DefIterator;
1236 typename std::iterator_traits<BaseT>::reference
operator*()
const {
1238 "Tried to access past the end of our iterator");
1242 using BaseT::operator++;
1245 "Tried to access past the end of the iterator");
1247 if (DefIterator != OriginalAccess->
defs_end())
1248 fillInCurrentPair();
1258 bool IsGuaranteedLoopInvariant(
Value *Ptr)
const;
1260 void fillInCurrentPair() {
1261 CurrentPair.first = *DefIterator;
1262 CurrentPair.second = Location;
1263 if (WalkingPhi && Location.
Ptr) {
1270 !IsGuaranteedLoopInvariant(
const_cast<Value *
>(Location.
Ptr)))
1271 CurrentPair.second =
1277 if (!Translator.PHITranslateValue(OriginalAccess->
getBlock(),
1280 Value *TransAddr = Translator.getAddr();
1281 if (TransAddr != Location.
Ptr) {
1282 CurrentPair.second = CurrentPair.second.getWithNewPtr(TransAddr);
1285 !IsGuaranteedLoopInvariant(
const_cast<Value *
>(TransAddr)))
1286 CurrentPair.second = CurrentPair.second.getWithNewSize(
1289 if (PerformedPhiTranslation)
1290 *PerformedPhiTranslation =
true;
1298 MemoryLocation Location;
1299 MemoryAccess *OriginalAccess =
nullptr;
1300 DominatorTree *DT =
nullptr;
1301 bool WalkingPhi =
false;
1302 bool *PerformedPhiTranslation =
nullptr;
1305 inline upward_defs_iterator
1307 bool *PerformedPhiTranslation =
nullptr) {
1313 inline iterator_range<upward_defs_iterator>
1331 template <
class T,
bool UseOptimizedChain = false>
1334 std::forward_iterator_tag, MemoryAccess *> {
1342 if (
auto *MUD = dyn_cast<MemoryUseOrDef>(MA)) {
1343 if (UseOptimizedChain && MUD->isOptimized())
1344 MA = MUD->getOptimized();
1346 MA = MUD->getDefiningAccess();
1361 inline iterator_range<def_chain_iterator<T>>
1363 #ifdef EXPENSIVE_CHECKS
1365 "UpTo isn't in the def chain!");
1378 #endif // LLVM_ANALYSIS_MEMORYSSA_H
A set of analyses that are preserved following a run of a transformation pass.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
static bool classof(const Value *V)
DefsOnlyType::const_reverse_self_iterator getReverseDefsIterator() const
A MemorySSAWalker that does no alias queries, or anything else.
user_iterator_impl< const User > const_user_iterator
@ MayAlias
The two locations may or may not alias.
void unorderedDeleteIncomingIf(Fn &&Pred)
This is an optimization pass for GlobalISel generic memory operations.
static void deleteNode(MemoryAccess *MA)
MemoryAccess * getOptimized() const
Return the MemoryAccess associated with the optimized use, or nullptr.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
DefsList * getWritableBlockDefs(const BasicBlock *BB) const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
MemoryAccess(const MemoryAccess &)=delete
BasicBlock * getIncomingBlock(MemoryAccess::const_user_iterator I) const
Return incoming basic block corresponding to value use iterator.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
PHITransAddr - An address value which tracks and handles phi translation.
const Value * Ptr
The address of the start of the location.
BasicBlock *const * const_block_iterator
A CRTP mix-in to automatically provide informational APIs needed for passes.
Iterator base class used to implement const and non-const iterators over the defining accesses of a M...
iterator_range< def_chain_iterator< T, true > > optimized_def_chain(T MA)
Replace within non kernel function use of LDS with pointer
Provide an iterator that walks defs, giving both the memory access, and the current pointer location,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
@ INVALID_MEMORYACCESS_ID
memoryaccess_def_iterator defs_begin()
This iterator walks over all of the defs in a given MemoryAccess.
Printer pass for MemorySSA.
MemoryLocation getWithNewSize(LocationSize NewSize) const
unsigned getID() const
Used for debugging and tracking things about MemoryAccesses.
void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal, SmallPtrSetImpl< BasicBlock * > &Visited)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
def_chain_iterator & operator++()
MemorySSAWalker(MemorySSA *)
void unorderedDeleteIncomingValue(const MemoryAccess *MA)
AllAccessType::reverse_self_iterator getReverseIterator()
The instances of the Type class are immutable: once they are created, they are never changed.
reverse_self_iterator getReverseIterator()
#define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS)
Macro for generating out-of-class operand accessor definitions.
MemoryAccess * getLiveOnEntryDef() const
The possible results of an alias query.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Represents phi nodes for memory accesses.
void print(raw_ostream &OS) const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Result(std::unique_ptr< MemorySSA > &&MSSA)
Represents read-only accesses to memory.
static unsigned getOperandNumForIncomingValue(unsigned I)
MemoryAccess * getClobberingMemoryAccess(MemoryAccess *) override
Does the same thing as getClobberingMemoryAccess(const Instruction *I), but takes a MemoryAccess inst...
iterator_range< upward_defs_iterator > upward_defs(const MemoryAccessPair &Pair, DominatorTree &DT)
static bool classof(const Value *MA)
An intrusive list with ownership and callbacks specified/controlled by ilist_traits,...
void setOptimizedAccessType(Optional< AliasResult > AR)
void(*)(DerivedUser *) DeleteValueTy
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
static bool classof(const Value *MA)
LLVM Basic Block Representation.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
const_block_iterator block_end() const
DefsOnlyType::const_self_iterator getDefsIterator() const
MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty, DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB, unsigned NumOperands)
static unsigned operands(const MemoryUseOrDef *MUD)
user_iterator iterator
The user iterators for a memory access.
MemoryPhi * getMemoryAccess(const BasicBlock *BB) const
static ChildIteratorType child_end(NodeRef N)
Legacy analysis pass which computes MemorySSA.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Compile-time customization of User operands.
AllAccessType::self_iterator getIterator()
Get the iterators for the all access list and the defs only list We default to the all access list.
const_block_iterator block_begin() const
memoryaccess_def_iterator defs_end()
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")
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
~MemoryUseOrDef()=default
(vector float) vec_cmpeq(*A, *B) C
static bool classof(const Value *MA)
upward_defs_iterator(const MemoryAccessPair &Info, DominatorTree *DT, bool *PerformedPhiTranslation=nullptr)
bool runOnFunction(Function &) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void print(raw_ostream &OS, const Module *M=nullptr) const override
print - Print out the internal state of the pass.
memoryaccess_def_iterator_base< MemoryAccess > memoryaccess_def_iterator
static bool classof(const Value *V)
virtual ~MemorySSAWalker()=default
Represent the analysis usage information of a pass.
virtual void invalidateInfo(MemoryAccess *)
Given a memory access, invalidate anything this walker knows about that access.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DefsOnlyType::reverse_self_iterator getReverseDefsIterator()
unsigned getValueID() const
Return an ID for the concrete type of this object.
static NodeRef getEntryNode(NodeRef N)
Result run(Function &F, FunctionAnalysisManager &AM)
void addIncoming(MemoryAccess *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This class implements an extremely fast bulk output stream that can only output to a stream.
static bool dominates(MachineBasicBlock &MBB, MachineBasicBlock::const_iterator A, MachineBasicBlock::const_iterator B)
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
User * getUser() const
Returns the User that contains this Use.
Analysis containing CSE Info
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess)
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
MemorySSAPrinterPass(raw_ostream &OS)
API to communicate dependencies between analyses during invalidation.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
static unsigned getIncomingValueNumForOperand(unsigned I)
void unorderedDeleteIncoming(unsigned I)
std::iterator_traits< BaseT >::reference operator*() const
BasicBlock * getBlock() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
AllAccessType::const_reverse_self_iterator getReverseIterator() const
BasicBlock * getPhiArgBlock() const
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
block_iterator block_begin()
upward_defs_iterator & operator++()
MemoryAccess * getClobberingMemoryAccess(const Instruction *I)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
MemoryAccess(LLVMContext &C, unsigned Vty, DeleteValueTy DeleteValue, BasicBlock *BB, unsigned NumOperands)
bool runOnFunction(Function &) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Optional< AliasResult > getOptimizedAccessType() const
void allocHungoffUses(unsigned N, bool IsPhi=false)
Allocate the array of Uses, followed by a pointer (with bottom bit set) to the User.
void print(raw_ostream &OS) const
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
const MemorySSA & getMSSA() const
iterator_range< const_block_iterator > blocks() const
MemoryAccess & operator=(const MemoryAccess &)=delete
Verifier pass for MemorySSA.
This is an important class for using LLVM in a threaded context.
bool operator==(const upward_defs_iterator &Other) const
iterator_range< def_chain_iterator< T > > def_chain(T MA, MemoryAccess *UpTo=nullptr)
bool operator==(const memoryaccess_def_iterator_base &Other) const
A special type used by analysis passes to provide an address that identifies that particular analysis...
const_op_range incoming_values() const
Encapsulates MemorySSA, including all data associated with memory accesses.
BasicBlock * getIncomingBlock(const Use &U) const
Return incoming basic block corresponding to an operand of the PHI.
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
MemorySSAWalkerPrinterPass(raw_ostream &OS)
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
std::unique_ptr< MemorySSA > MSSA
MemoryAccess::iterator ChildIteratorType
Use delete by default for iplist and ilist.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
DominatorTree & getDomTree() const
InsertionPlace
Used in various insertion functions to specify whether we are talking about the beginning or end of a...
static ChildIteratorType child_begin(NodeRef N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
const_user_iterator const_iterator
upward_defs_iterator upward_defs_begin(const MemoryAccessPair &Pair, DominatorTree &DT, bool *PerformedPhiTranslation=nullptr)
BasicBlock * getPhiArgBlock() const
op_range incoming_values()
@ BasicBlock
Various leaf nodes.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess)
MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB, unsigned Ver)
void unorderedDeleteIncomingBlock(const BasicBlock *BB)
A Module instance is used to store all the information related to an LLVM module.
memoryaccess_def_iterator_base()=default
An analysis that produces MemorySSA for a function.
A CRTP mix-in that provides informational APIs needed for analysis passes.
MemoryAccess * getIncomingValue(unsigned I) const
Return incoming value number x.
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< const MemoryAccess > const_memoryaccess_def_iterator
void setOperand(unsigned i, Value *Val)
std::pair< MemoryAccess *, MemoryLocation > MemoryAccessPair
const DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
block_iterator block_end()
self_iterator getIterator()
void allocHungoffUses(unsigned N)
this is more complicated than the generic User::allocHungoffUses, because we have to allocate Uses fo...
std::iterator_traits< BaseT >::pointer operator*() const
void setIncomingValue(unsigned I, MemoryAccess *V)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Machine Check Debug Module
void setIncomingBlock(unsigned I, BasicBlock *BB)
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)
std::pair< const MemoryAccess *, MemoryLocation > ConstMemoryAccessPair
memoryaccess_def_iterator_base & operator++()
user_iterator_impl< User > user_iterator
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
constexpr static LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
void setOptimized(MemoryAccess *MA)
Iterator for intrusive lists based on ilist_node.
AllAccessType::const_self_iterator getIterator() const
void resetOptimized()
Reset the ID of what this MemoryUse was optimized to, causing it to be rewalked by the walker if nece...
bool isOptimized() const
Do we have an optimized use?
void setOptimized(MemoryAccess *)
Sets the optimized use for a MemoryDef.
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds=0)
Class that has the common methods + fields of memory uses/defs.
static ChildIteratorType child_begin(NodeRef N)
static Use * op_end(MemoryUseOrDef *MUD)
AccessList * getWritableBlockAccesses(const BasicBlock *BB) const
#define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS)
Macro for generating in-class operand accessor declarations.
Printer pass for MemorySSA via the walker.
iterator_range< block_iterator > blocks()
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
DefsOnlyType::self_iterator getDefsIterator()
void deleteValue()
Delete a pointer to a generic Value.
Align max(MaybeAlign Lhs, Align Rhs)
A range adaptor for a pair of iterators.
FixedNumOperandTraits - determine the allocation regime of the Use array when it is a prefix to the U...
A simple intrusive list implementation.
MemoryAccess * getIncomingValueForBlock(const BasicBlock *BB) const
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
A container for analyses that lazily runs them and caches their results.
FunctionPass class - This class is used to implement most global optimizations.
void setOptimized(MemoryAccess *DMA)
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
bool isOptimized() const
Whether the MemoryUse is optimized.
upward_defs_iterator upward_defs_end()
static bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA)
bool VerifyMemorySSA
Enables verification of MemorySSA.
This is the generic walker interface for walkers of MemorySSA.
Value * getOperand(unsigned i) const
MemorySSAPrinterLegacyPass()
HungoffOperandTraits - determine the allocation regime of the Use array when it is not a prefix to th...
static NodeRef getEntryNode(NodeRef N)
bool operator==(const def_chain_iterator &O) const
memoryaccess_def_iterator_base(T *Start)
void setDefiningAccess(MemoryAccess *DMA, bool Optimized=false, Optional< AliasResult > AR=AliasResult(AliasResult::MayAlias))
early cse Early CSE w MemorySSA
LLVM Value Representation.
Extension point for the Value hierarchy.
MemoryAccess * getOptimized() const
Representation for a specific memory location.
Walks the defining accesses of MemoryDefs.
Optional< std::vector< StOtherPiece > > Other
A Use represents the edge between a Value definition and its users.
static ChildIteratorType child_end(NodeRef N)
static Use * op_begin(MemoryUseOrDef *MUD)
MemoryAccess * getOptimized() const