30 #define DEBUG_TYPE "memoryssa" 47 auto Cached = CachedPreviousDef.find(BB);
48 if (Cached != CachedPreviousDef.end()) {
49 return Cached->second;
54 MemoryAccess *Result = getPreviousDefFromEnd(Pred, CachedPreviousDef);
55 CachedPreviousDef.insert({BB, Result});
59 if (VisitedBlocks.count(BB)) {
64 CachedPreviousDef.insert({BB, Result});
68 if (VisitedBlocks.insert(BB).second) {
76 PhiOps.
push_back(getPreviousDefFromEnd(Pred, CachedPreviousDef));
83 auto *Result = tryRemoveTrivialPhi(Phi, PhiOps);
87 Phi = MSSA->createMemoryPhi(BB);
103 InsertedPHIs.push_back(Phi);
109 VisitedBlocks.erase(BB);
110 CachedPreviousDef.insert({BB, Result});
121 if (
auto *LocalResult = getPreviousDefInBlock(MA))
124 return getPreviousDefRecursive(MA->
getBlock(), CachedPreviousDef);
136 if (!isa<MemoryUse>(MA)) {
139 if (Iter != Defs->rend())
145 if (!isa<MemoryUse>(U))
146 return cast<MemoryAccess>(&U);
163 return getPreviousDefRecursive(BB, CachedPreviousDef);
172 for (
auto &U : Uses) {
173 if (
MemoryPhi *UsePhi = dyn_cast<MemoryPhi>(&*U)) {
174 auto OperRange = UsePhi->operands();
175 tryRemoveTrivialPhi(UsePhi, OperRange);
186 template <
class RangeType>
188 RangeType &Operands) {
190 if (NonOptPhis.count(Phi))
195 for (
auto &
Op : Operands) {
197 if (
Op == Phi ||
Op == Same)
202 Same = cast<MemoryAccess>(&*
Op);
214 return recursePhi(Same);
218 InsertedPHIs.clear();
236 assert(i != -1 &&
"Should have found the basic block in the phi");
255 InsertedPHIs.clear();
265 if (DefBeforeSameBlock) {
281 if (!DefBeforeSameBlock) {
296 while (!FixupList.empty()) {
297 unsigned StartingPHISize = InsertedPHIs.size();
298 fixupDefs(FixupList);
301 FixupList.append(InsertedPHIs.begin() + StartingPHISize, InsertedPHIs.end());
312 if (
auto *MD = dyn_cast<MemoryDef>(FirstDef))
318 for (
auto &MP : InsertedPHIs) {
319 MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MP);
329 for (
auto &Var : Vars) {
330 MemoryAccess *NewDef = dyn_cast_or_null<MemoryAccess>(Var);
338 if (
MemoryPhi *Phi = dyn_cast<MemoryPhi>(NewDef))
339 NonOptPhis.erase(Phi);
342 if (++DefIter != Defs->end()) {
343 cast<MemoryDef>(DefIter)->setDefiningAccess(NewDef);
357 while (!Worklist.
empty()) {
363 auto *FirstDef = &*Defs->begin();
365 assert(!isa<MemoryPhi>(FirstDef) &&
366 "Should have already handled phi nodes!");
370 "Should have dominated the new access");
375 cast<MemoryDef>(FirstDef)->setDefiningAccess(getPreviousDef(FirstDef));
379 for (
const auto *S :
successors(FixupBlock)) {
387 if (!Seen.
insert(S).second)
398 MPhi->unorderedDeleteIncomingBlock(From);
399 if (MPhi->getNumIncomingValues() == 1)
416 if (MPhi->getNumIncomingValues() == 1)
426 if (
MemoryUseOrDef *DefMUD = dyn_cast<MemoryUseOrDef>(InsnDefining)) {
429 assert(DefMUDI &&
"Found MemoryUseOrDef with no Instruction.");
431 cast_or_null<Instruction>(VMap.
lookup(DefMUDI)))
435 MemoryPhi *DefPhi = cast<MemoryPhi>(InsnDefining);
437 InsnDefining = NewDefPhi;
439 assert(InsnDefining &&
"Defining instruction cannot be nullptr.");
454 dyn_cast_or_null<Instruction>(VMap.
lookup(Insn))) {
456 NewInsn, GetNewDefiningAccess(MUD->getDefiningAccess()), MUD);
466 bool IgnoreIncomingWithNoClones) {
470 assert(Phi && NewPhi &&
"Invalid Phi nodes.");
480 else if (IgnoreIncomingWithNoClones)
487 if (!NewPhiBBPreds.
count(IncBB))
491 if (
MemoryUseOrDef *IncMUD = dyn_cast<MemoryUseOrDef>(IncomingAccess)) {
494 assert(IncI &&
"Found MemoryUseOrDef with no Instruction.");
496 cast_or_null<Instruction>(VMap.
lookup(IncI))) {
499 "MemoryUseOrDef cannot be null, all preds processed.");
502 NewPhi->addIncoming(IncMUD, IncBB);
504 MemoryPhi *IncPhi = cast<MemoryPhi>(IncomingAccess);
508 NewPhi->addIncoming(IncPhi, IncBB);
519 "Cloned block should have no accesses");
523 MemoryPhi *NewPhi = MSSA->createMemoryPhi(NewBlock);
524 MPhiMap[MPhi] = NewPhi;
527 cloneUsesAndDefs(BB, NewBlock, VMap, MPhiMap);
530 for (
auto BB : llvm::concat<BasicBlock *const>(LoopBlocks, ExitBlocks))
533 for (
auto BB : llvm::concat<BasicBlock *const>(LoopBlocks, ExitBlocks))
536 FixPhiIncomingValues(MPhi, cast<MemoryPhi>(NewPhi));
548 MPhiMap[MPhi] = MPhi->getIncomingValueForBlock(P1);
549 cloneUsesAndDefs(BB, P1, VM, MPhiMap);
552 template <
typename Iter>
553 void MemorySSAUpdater::privateUpdateExitBlocksForClonedLoop(
558 for (
auto *Exit : ExitBlocks)
571 privateUpdateExitBlocksForClonedLoop(ExitBlocks,
std::begin(Arr),
578 auto GetPtr = [&](
const std::unique_ptr<ValueToValueMapTy> &
I) {
581 using MappedIteratorType =
584 auto MapBegin = MappedIteratorType(VMaps.begin(), GetPtr);
585 auto MapEnd = MappedIteratorType(VMaps.end(), GetPtr);
586 privateUpdateExitBlocksForClonedLoop(ExitBlocks, MapBegin, MapEnd, DT);
593 for (
auto &Update : Updates) {
594 if (Update.getKind() == DT.
Insert)
595 InsertUpdates.
push_back({DT.Insert, Update.getFrom(), Update.getTo()});
597 RevDeleteUpdates.
push_back({DT.
Insert, Update.getFrom(), Update.getTo()});
600 if (!RevDeleteUpdates.
empty()) {
616 for (
auto &Update : RevDeleteUpdates)
635 return &*(--Defs->
end());
640 for (
auto &Pair : children<GraphDiffInvBBPair>({GD, BB})) {
655 if (IDom->getBlock() != BB) {
656 BB = IDom->getBlock();
662 assert(Count == 1 && Pred &&
"Single predecessor expected.");
672 auto FindNearestCommonDominator =
675 for (
auto *BB : BBSet)
682 auto GetNoLongerDomBlocks =
685 if (PrevIDom == CurrIDom)
687 BlocksPrevDom.push_back(PrevIDom);
691 if (UpIDom == CurrIDom)
693 BlocksPrevDom.push_back(UpIDom);
718 for (
auto &Edge : Updates) {
720 auto &AddedBlockSet = PredMap[BB].Added;
721 AddedBlockSet.
insert(Edge.getFrom());
727 for (
auto &BBPredPair : PredMap) {
728 auto *BB = BBPredPair.first;
729 const auto &AddedBlockSet = BBPredPair.second.Added;
730 auto &PrevBlockSet = BBPredPair.second.Prev;
731 for (
auto &Pair : children<GraphDiffInvBBPair>({GD, BB})) {
733 if (!AddedBlockSet.count(Pi))
734 PrevBlockSet.insert(Pi);
735 EdgeCountMap[{Pi, BB}]++;
738 if (PrevBlockSet.empty()) {
739 assert(
pred_size(BB) == AddedBlockSet.size() &&
"Duplicate edges added.");
742 <<
"Adding a predecessor to a block with no predecessors. " 743 "This must be an edge added to a new, likely cloned, block. " 744 "Its memory accesses must be already correct, assuming completed " 745 "via the updateExitBlocksForClonedLoop API. " 746 "Assert a single such edge is added so no phi addition or " 747 "additional processing is required.\n");
748 assert(AddedBlockSet.size() == 1 &&
749 "Can only handle adding one predecessor to a new block.");
756 for (
auto *BB : NewBlocks)
764 for (
auto &Edge : Updates) {
766 if (PredMap.count(BB) && !MSSA->getMemoryAccess(BB))
767 MSSA->createMemoryPhi(BB);
771 for (
auto &BBPredPair : PredMap) {
772 auto *BB = BBPredPair.first;
773 const auto &PrevBlockSet = BBPredPair.second.Prev;
774 const auto &AddedBlockSet = BBPredPair.second.Added;
775 assert(!PrevBlockSet.empty() &&
776 "At least one previous predecessor must exist.");
785 for (
auto *AddedPred : AddedBlockSet) {
786 auto *DefPn = GetLastDef(AddedPred);
787 assert(DefPn !=
nullptr &&
"Unable to find last definition.");
788 LastDefAddedPred[AddedPred] = DefPn;
791 MemoryPhi *NewPhi = MSSA->getMemoryAccess(BB);
795 for (
auto *Pred : AddedBlockSet) {
796 auto *LastDefForPred = LastDefAddedPred[Pred];
797 for (
int I = 0,
E = EdgeCountMap[{Pred, BB}];
I <
E; ++
I)
803 auto *P1 = *PrevBlockSet.begin();
808 bool InsertPhi =
false;
809 for (
auto LastDefPredPair : LastDefAddedPred)
810 if (DefP1 != LastDefPredPair.second) {
826 for (
auto *Pred : AddedBlockSet) {
827 auto *LastDefForPred = LastDefAddedPred[Pred];
828 for (
int I = 0,
E = EdgeCountMap[{Pred, BB}];
I <
E; ++
I)
831 for (
auto *Pred : PrevBlockSet)
832 for (
int I = 0,
E = EdgeCountMap[{Pred, BB}];
I <
E; ++
I)
843 BasicBlock *PrevIDom = FindNearestCommonDominator(PrevBlockSet);
844 assert(PrevIDom &&
"Previous IDom should exists");
846 assert(NewIDom &&
"BB should have a new valid idom");
848 "New idom should dominate old idom");
849 GetNoLongerDomBlocks(PrevIDom, NewIDom, BlocksWithDefsToReplace);
854 if (!BlocksToProcess.
empty()) {
857 BlocksToProcess.
end());
860 for (
auto *BBIDF : IDFBlocks) {
861 if (
auto *IDFPhi = MSSA->getMemoryAccess(BBIDF)) {
864 for (
unsigned I = 0,
E = IDFPhi->getNumIncomingValues();
I <
E; ++
I)
865 IDFPhi->setIncomingValue(
I, GetLastDef(IDFPhi->getIncomingBlock(
I)));
867 IDFPhi = MSSA->createMemoryPhi(BBIDF);
868 for (
auto &Pair : children<GraphDiffInvBBPair>({GD, BBIDF})) {
870 IDFPhi->addIncoming(GetLastDef(Pi), Pi);
879 for (
auto *BlockWithDefsToReplace : BlocksWithDefsToReplace) {
880 if (
auto DefsList = MSSA->getWritableBlockDefs(BlockWithDefsToReplace)) {
881 for (
auto &DefToReplaceUses : *DefsList) {
882 BasicBlock *DominatingBlock = DefToReplaceUses.getBlock();
884 E = DefToReplaceUses.use_end();
889 if (
MemoryPhi *UsrPhi = dyn_cast<MemoryPhi>(Usr)) {
890 BasicBlock *DominatedBlock = UsrPhi->getIncomingBlock(U);
891 if (!DT.
dominates(DominatingBlock, DominatedBlock))
892 U.
set(GetLastDef(DominatedBlock));
895 if (!DT.
dominates(DominatingBlock, DominatedBlock)) {
896 if (
auto *DomBlPhi = MSSA->getMemoryAccess(DominatedBlock))
900 assert(IDom &&
"Block must have a valid IDom.");
901 U.
set(GetLastDef(IDom->getBlock()));
903 cast<MemoryUseOrDef>(Usr)->resetOptimized();
913 template <
class WhereType>
917 for (
auto *U : What->
users())
918 if (
MemoryPhi *PhiUser = dyn_cast<MemoryPhi>(U))
919 NonOptPhis.insert(PhiUser);
925 MSSA->moveTo(What, BB, Where);
928 if (
auto *MD = dyn_cast<MemoryDef>(What))
950 return moveTo(What, BB, Where);
963 if ((FirstInNew = MSSA->getMemoryAccess(&
I)))
968 auto *MUD = cast<MemoryUseOrDef>(FirstInNew);
973 : cast<MemoryUseOrDef>(&*NextIt);
977 Accs = MSSA->getWritableBlockAccesses(From);
985 assert(MSSA->getBlockAccesses(To) ==
nullptr &&
986 "To block is expected to be free of MemoryAccesses.");
987 moveAllAccesses(From, To, Start);
989 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
990 MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
996 "From block is expected to have a single predecessor (To).");
997 moveAllAccesses(From, To, Start);
999 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
1000 MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
1010 MA = cast<MemoryAccess>(
Arg);
1019 bool IdenticalEdgesWereMerged) {
1020 assert(!MSSA->getWritableBlockAccesses(New) &&
1021 "Access list should be null for a new block.");
1022 MemoryPhi *Phi = MSSA->getMemoryAccess(Old);
1027 "Should have moved all predecessors.");
1030 assert(!Preds.
empty() &&
"Must be moving at least one predecessor to the " 1031 "new immediate predecessor.");
1032 MemoryPhi *NewPhi = MSSA->createMemoryPhi(New);
1036 if (!IdenticalEdgesWereMerged)
1038 "If identical edges were not merged, we cannot have duplicate " 1039 "blocks in the predecessors");
1041 if (PredsSet.count(B)) {
1042 NewPhi->addIncoming(MA, B);
1043 if (!IdenticalEdgesWereMerged)
1049 Phi->addIncoming(NewPhi, New);
1056 assert(!MSSA->isLiveOnEntryDef(MA) &&
1057 "Trying to remove the live on entry def");
1061 if (
MemoryPhi *MP = dyn_cast<MemoryPhi>(MA)) {
1068 assert((NewDefTarget || MP->use_empty()) &&
1069 "We can't delete this memory phi");
1071 NewDefTarget = cast<MemoryUseOrDef>(MA)->getDefiningAccess();
1075 if (!isa<MemoryUse>(MA) && !MA->
use_empty()) {
1091 if (
auto *MUD = dyn_cast<MemoryUseOrDef>(U.
getUser()))
1092 MUD->resetOptimized();
1093 U.
set(NewDefTarget);
1099 MSSA->removeFromLookups(MA);
1100 MSSA->removeFromLists(MA);
1108 assert(TI &&
"Basic block expected to have a terminator instruction");
1110 if (!DeadBlocks.count(Succ))
1111 if (
MemoryPhi *MP = MSSA->getMemoryAccess(Succ)) {
1112 MP->unorderedDeleteIncomingBlock(BB);
1113 if (MP->getNumIncomingValues() == 1)
1127 for (
auto AB = Acc->begin(), AE = Acc->end(); AB != AE;) {
1130 MSSA->removeFromLookups(MA);
1131 MSSA->removeFromLists(MA);
1139 MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(I, Definition);
1140 MSSA->insertIntoListsForBlock(NewAccess, BB, Point);
1147 "New and old access must be in the same block");
1148 MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(I, Definition);
1149 MSSA->insertIntoListsBefore(NewAccess, InsertPt->
getBlock(),
1157 "New and old access must be in the same block");
1158 MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(I, Definition);
1159 MSSA->insertIntoListsBefore(NewAccess, InsertPt->
getBlock(),
const_iterator end(StringRef path)
Get end iterator over path.
AccessList * getWritableBlockAccesses(const BasicBlock *BB) const
bool hasNPredecessors(unsigned N) const
Return true if this block has exactly N predecessors.
static MemoryAccess * onlySingleValue(MemoryPhi *MP)
If all arguments of a MemoryPHI are defined by the same incoming argument, return that argument...
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
void dropAllReferences()
Drop all references to operands.
This class represents lattice values for constants.
AllAccessType::self_iterator getIterator()
Get the iterators for the all access list and the defs only list We default to the all access list...
bool dominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in potentially different blocks, determine whether MemoryAccess A dominates...
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
void updateExitBlocksForClonedLoop(ArrayRef< BasicBlock *> ExitBlocks, const ValueToValueMapTy &VMap, DominatorTree &DT)
Update phi nodes in exit block successors following cloning.
void removeDuplicatePhiEdgesBetween(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To to have a single incoming edge from From, following a CFG change that repl...
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
void applyInsertUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT)
Apply CFG insert updates, analogous with the DT edge updates.
void push_back(const T &Elt)
const AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
void removeBlocks(const SmallPtrSetImpl< BasicBlock *> &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
bool hasValueHandle() const
Return true if there is a value handle associated with this value.
void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where)
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
void insertUse(MemoryUse *Use)
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
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...
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...
iterator begin()
Instruction iterator methods.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Represents read-only accesses to memory.
void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
void renamePass(BasicBlock *BB, MemoryAccess *IncomingVal, SmallPtrSetImpl< BasicBlock *> &Visited)
block_iterator block_begin()
A Use represents the edge between a Value definition and its users.
void setDefiningBlocks(const SmallPtrSetImpl< BasicBlock *> &Blocks)
Give the IDF calculator the set of blocks in which the value is defined.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void applyUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT)
Apply CFG updates, analogous with the DT edge updates.
void insertIntoListsForBlock(MemoryAccess *, const BasicBlock *, InsertionPlace)
A simple intrusive list implementation.
void removeMemoryAccess(MemoryAccess *)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
static void ValueIsRAUWd(Value *Old, Value *New)
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
MemoryUseOrDef * createMemoryAccessBefore(Instruction *I, MemoryAccess *Definition, MemoryUseOrDef *InsertPt)
Create a MemoryAccess in MemorySSA before or after an existing MemoryAccess.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
MemoryAccess * getIncomingValue(unsigned I) const
Return incoming value number x.
use_iterator_impl< Use > use_iterator
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
static constexpr UpdateKind Insert
AllAccessType::reverse_self_iterator getReverseIterator()
LLVM Basic Block Representation.
static void setMemoryPhiValueForBlock(MemoryPhi *MP, const BasicBlock *BB, MemoryAccess *NewDef)
Value handle that tracks a Value across RAUW.
size_t size() const
size - Get the array size.
DomTreeNodeBase * getIDom() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
void addIncoming(MemoryAccess *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
InsertionPlace
Used in various insertion functions to specify whether we are talking about the beginning or end of a...
void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was spliced into From and To.
Interval::pred_iterator pred_end(Interval *I)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
void updateForClonedLoop(const LoopBlocksRPO &LoopBlocks, ArrayRef< BasicBlock *> ExitBlocks, const ValueToValueMapTy &VM, bool IgnoreIncomingWithNoClones=false)
Update MemorySSA after a loop was cloned, given the blocks in RPO order, the exit blocks and a 1:1 ma...
MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point)
Create a MemoryAccess in MemorySSA at a specified point in a block, with a specified clobbering defin...
Compute iterated dominance frontiers using a linear time algorithm.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
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.
void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
MemoryUseOrDef * createDefinedAccess(Instruction *, MemoryAccess *, const MemoryUseOrDef *Template=nullptr)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
A SetVector that performs no allocations if smaller than a certain size.
void setDefiningAccess(MemoryAccess *DMA, bool Optimized=false, Optional< AliasResult > AR=MayAlias)
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
BlockVerifier::State From
void calculate(SmallVectorImpl< BasicBlock *> &IDFBlocks)
Calculate iterated dominance frontiers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Module.h This file contains the declarations for the Module class.
void wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, BasicBlock *New, ArrayRef< BasicBlock *> Preds, bool IdenticalEdgesWereMerged=true)
A new empty BasicBlock (New) now branches directly to Old.
BasicBlock * getBlock() const
pred_range predecessors(BasicBlock *BB)
MemoryAccess * getLiveOnEntryDef() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class that has the common methods + fields of memory uses/defs.
iterator_range< user_iterator > users()
unsigned getNumIncomingValues() const
Return the number of incoming edges.
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
amdgpu Simplify well known AMD library false Value Value * Arg
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
block_iterator block_end()
LLVM_NODISCARD bool empty() const
unsigned pred_size(const BasicBlock *BB)
Get the number of predecessors of BB.
MemoryUseOrDef * createMemoryAccessAfter(Instruction *I, MemoryAccess *Definition, MemoryAccess *InsertPt)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was merged into To.
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
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...
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
Determine the iterated dominance frontier, given a set of defining blocks, and optionally, a set of live-in blocks.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
succ_range successors(Instruction *I)
DefsOnlyType::reverse_self_iterator getReverseDefsIterator()
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
Represents phi nodes for memory accesses.
DefsList * getWritableBlockDefs(const BasicBlock *BB) const
OutputIt copy(R &&Range, OutputIt Out)
void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where)
void updateForClonedBlockIntoPred(BasicBlock *BB, BasicBlock *P1, const ValueToValueMapTy &VM)
reverse_iterator rbegin()
bool empty() const
empty - Check if the array is empty.
const BasicBlock * getParent() const