24#define DEBUG_TYPE "memoryssa"
53 enum class ResumePoint { EnterBlock, ResumeSinglePred, RunPredLoop };
57 ResumePoint Resume = ResumePoint::EnterBlock;
66 bool PendingIncoming =
false;
67 bool UniqueIncomingAccess =
true;
75 SingleAccess = Incoming;
76 else if (Incoming != SingleAccess)
77 UniqueIncomingAccess =
false;
81 using ResumePoint = StackFrame::ResumePoint;
91 CachedPreviousDef.insert({Pred, Result});
100 while (!WorkStack.
empty()) {
104 StackFrame &
F = WorkStack.
back();
108 case ResumePoint::EnterBlock: {
111 auto Cached = CachedPreviousDef.find(CurBB);
112 if (Cached != CachedPreviousDef.end()) {
113 Returned = Cached->second;
130 CachedPreviousDef.insert({CurBB, Result});
135 F.Resume = ResumePoint::ResumeSinglePred;
145 CachedPreviousDef.insert({CurBB, Result});
154 F.Resume = ResumePoint::RunPredLoop;
158 case ResumePoint::ResumeSinglePred: {
160 CachedPreviousDef.insert({CurBB, Returned});
165 case ResumePoint::RunPredLoop: {
169 if (
F.PendingIncoming) {
171 F.incorporate(Returned);
172 F.PendingIncoming =
false;
176 bool Suspended =
false;
177 for (;
F.PredIt !=
pred_end(CurBB); ++
F.PredIt) {
181 if (
MemoryAccess *IncomingAccess = GetLocalDefFromEnd(Pred)) {
182 F.incorporate(IncomingAccess);
184 F.PendingIncoming =
true;
201 auto *Result = tryRemoveTrivialPhi(Phi,
F.PhiOps);
203 if (Result == Phi &&
F.UniqueIncomingAccess &&
F.SingleAccess) {
207 assert(Phi->operands().empty() &&
"Expected empty Phi");
208 Phi->replaceAllUsesWith(
F.SingleAccess);
211 Result =
F.SingleAccess;
212 }
else if (Result == Phi && !(
F.UniqueIncomingAccess &&
F.SingleAccess)) {
214 Phi = MSSA->createMemoryPhi(CurBB);
219 if (Phi->getNumOperands() != 0) {
221 if (!std::equal(Phi->op_begin(), Phi->op_end(),
F.PhiOps.begin())) {
229 Phi->addIncoming(&*
F.PhiOps[
I++], Pred);
230 InsertedPHIs.push_back(Phi);
237 CachedPreviousDef.insert({CurBB, Result});
253 if (
auto *LocalResult = getPreviousDefInBlock(MA))
255 DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> CachedPreviousDef;
256 return getPreviousDefIterative(MA->
getBlock(), CachedPreviousDef);
263 auto *Defs = MSSA->getBlockDefs(MA->
getBlock());
271 if (Iter != Defs->rend())
275 auto End = MSSA->getBlockAccesses(MA->
getBlock())->rend();
290 auto *Defs = MSSA->getBlockDefs(BB);
293 CachedPreviousDef.insert({BB, &*Defs->
rbegin()});
294 return &*Defs->rbegin();
297 return getPreviousDefIterative(BB, CachedPreviousDef);
303 TrackingVH<MemoryAccess> Res(Phi);
305 std::copy(
Phi->user_begin(),
Phi->user_end(), std::back_inserter(
Uses));
308 tryRemoveTrivialPhi(UsePhi);
318 assert(Phi &&
"Can only remove concrete Phi.");
319 auto OperRange =
Phi->operands();
320 return tryRemoveTrivialPhi(Phi, OperRange);
322template <
class RangeType>
324 RangeType &Operands) {
326 if (NonOptPhis.count(Phi))
330 MemoryAccess *Same =
nullptr;
331 for (
auto &
Op : Operands) {
333 if (
Op == Phi ||
Op == Same)
342 return MSSA->getLiveOnEntryDef();
344 Phi->replaceAllUsesWith(Same);
350 return recursePhi(Same);
354 VisitedBlocks.clear();
355 InsertedPHIs.clear();
371 if (!RenameUses && !InsertedPHIs.empty()) {
372 auto *Defs = MSSA->getBlockDefs(MU->
getBlock());
374 assert((!Defs || (++Defs->begin() == Defs->end())) &&
375 "Block may have only a Phi or no defs");
378 if (RenameUses && InsertedPHIs.size()) {
382 if (
auto *Defs = MSSA->getBlockDefs(StartBlock)) {
387 FirstDef = MD->getDefiningAccess();
389 MSSA->renamePass(MU->
getBlock(), FirstDef, Visited);
393 for (
auto &MP : InsertedPHIs)
395 MSSA->renamePass(Phi->getBlock(),
nullptr, Visited);
405 assert(i != -1 &&
"Should have found the basic block in the phi");
424 if (!MSSA->DT->isReachableFromEntry(MD->
getBlock())) {
429 VisitedBlocks.clear();
430 InsertedPHIs.clear();
434 bool DefBeforeSameBlock =
false;
438 DefBeforeSameBlock =
true;
444 if (DefBeforeSameBlock) {
448 User *Usr = U.getUser();
463 unsigned NewPhiIndex = InsertedPHIs.
size();
464 if (!DefBeforeSameBlock) {
486 for (
const auto &VH : InsertedPHIs)
488 DefiningBlocks.
insert(RealPHI->getBlock());
494 for (
auto *BBIDF : IDFBlocks) {
495 auto *MPhi = MSSA->getMemoryAccess(BBIDF);
497 MPhi = MSSA->createMemoryPhi(BBIDF);
500 ExistingPhis.
insert(MPhi);
508 NonOptPhis.insert(MPhi);
510 for (
auto &MPhi : NewInsertedPHIs) {
511 auto *BBIDF = MPhi->getBlock();
514 MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), Pred);
520 NewPhiIndex = InsertedPHIs.size();
521 for (
auto &MPhi : NewInsertedPHIs) {
522 InsertedPHIs.push_back(&*MPhi);
530 unsigned NewPhiIndexEnd = InsertedPHIs.size();
531 fixupDefs(FixupList);
532 assert(NewPhiIndexEnd == InsertedPHIs.size() &&
533 "Should not insert new phis during fixupDefs()");
536 unsigned NewPhiSize = NewPhiIndexEnd - NewPhiIndex;
538 tryRemoveTrivialPhis(
ArrayRef<WeakVH>(&InsertedPHIs[NewPhiIndex], NewPhiSize));
547 MemoryAccess *FirstDef = &*MSSA->getBlockDefs(StartBlock)->begin();
553 MSSA->renamePass(MD->
getBlock(), FirstDef, Visited);
556 for (
auto &MP : InsertedPHIs) {
559 MSSA->renamePass(Phi->getBlock(),
nullptr, Visited);
563 for (
const auto &MP : ExistingPhis) {
566 MSSA->renamePass(Phi->getBlock(),
nullptr, Visited);
574 for (
const auto &Var : Vars) {
584 NonOptPhis.erase(Phi);
587 if (++DefIter != Defs->end()) {
602 while (!Worklist.
empty()) {
606 if (
auto *Defs = MSSA->getBlockDefs(FixupBlock)) {
607 auto *FirstDef = &*Defs->begin();
610 "Should have already handled phi nodes!");
613 assert(MSSA->dominates(NewDef, FirstDef) &&
614 "Should have dominated the new access");
620 for (
const auto *S :
successors(FixupBlock)) {
623 if (
auto *MP = MSSA->getMemoryAccess(S))
628 if (!Seen.
insert(S).second)
638 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(To)) {
639 MPhi->unorderedDeleteIncomingBlock(From);
640 tryRemoveTrivialPhi(MPhi);
646 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(To)) {
656 tryRemoveTrivialPhi(MPhi);
684 assert(DefMUDI &&
"Found MemoryUseOrDef with no Instruction.");
685 if (!IsInClonedRegion(DefMUDI->
getParent()))
689 InsnDefining = NewDefMUDI ? MSSA->
getMemoryAccess(NewDefMUDI) :
nullptr;
693 DefMUD->getDefiningAccess(), VMap, MPhiMap, MSSA, IsInClonedRegion);
698 InsnDefining = NewDefPhi;
700 assert(InsnDefining &&
"Defining instruction cannot be nullptr.");
704void MemorySSAUpdater::cloneUsesAndDefs(
707 bool CloneWasSimplified) {
711 for (
const MemoryAccess &MA : *Acc) {
721 if (Instruction *NewInsn =
723 MemoryAccess *NewUseOrDef = MSSA->createDefinedAccess(
726 MPhiMap, MSSA, IsInClonedRegion),
727 CloneWasSimplified ?
nullptr : MUD,
730 MSSA->insertIntoListsForBlock(NewUseOrDef, NewBB,
MemorySSA::End);
738 auto *MPhi = MSSA->getMemoryAccess(Header);
744 auto *NewMPhi = MSSA->createMemoryPhi(BEBlock);
745 bool HasUniqueIncomingValue =
true;
747 for (
unsigned I = 0, E = MPhi->getNumIncomingValues();
I != E; ++
I) {
750 if (IBB != Preheader) {
751 NewMPhi->addIncoming(
IV, IBB);
752 if (HasUniqueIncomingValue) {
755 else if (UniqueValue !=
IV)
756 HasUniqueIncomingValue =
false;
763 auto *AccFromPreheader = MPhi->getIncomingValueForBlock(Preheader);
764 MPhi->setIncomingValue(0, AccFromPreheader);
765 MPhi->setIncomingBlock(0, Preheader);
766 for (
unsigned I = MPhi->getNumIncomingValues() - 1;
I >= 1; --
I)
767 MPhi->unorderedDeleteIncoming(
I);
768 MPhi->addIncoming(NewMPhi, BEBlock);
772 tryRemoveTrivialPhi(NewMPhi);
778 bool IgnoreIncomingWithNoClones) {
786 assert(Phi && NewPhi &&
"Invalid Phi nodes.");
790 for (
unsigned It = 0, E = Phi->getNumIncomingValues(); It < E; ++It) {
791 MemoryAccess *IncomingAccess = Phi->getIncomingValue(It);
792 BasicBlock *IncBB = Phi->getIncomingBlock(It);
796 else if (IgnoreIncomingWithNoClones)
803 if (!NewPhiBBPreds.
count(IncBB))
813 MPhiMap[Phi] = SingleAccess;
823 assert(!MSSA->getBlockAccesses(NewBlock) &&
824 "Cloned block should have no accesses");
827 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(BB)) {
828 MemoryPhi *NewPhi = MSSA->createMemoryPhi(NewBlock);
829 MPhiMap[MPhi] = NewPhi;
832 cloneUsesAndDefs(BB, NewBlock, VMap, MPhiMap, IsInClonedRegion);
835 for (
auto *BB : Blocks)
838 for (
auto *BB : Blocks)
839 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(BB))
855 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(BB))
856 MPhiMap[MPhi] = MPhi->getIncomingValueForBlock(P1);
858 BB, P1, VM, MPhiMap, [&](
BasicBlock *CheckBB) {
return BB == CheckBB; },
862template <
typename Iter>
863void MemorySSAUpdater::privateUpdateExitBlocksForClonedLoop(
868 for (
auto *Exit : ExitBlocks)
881 privateUpdateExitBlocksForClonedLoop(ExitBlocks, std::begin(Arr),
888 auto GetPtr = [&](
const std::unique_ptr<ValueToValueMapTy> &
I) {
891 using MappedIteratorType =
894 auto MapBegin = MappedIteratorType(VMaps.begin(), GetPtr);
895 auto MapEnd = MappedIteratorType(VMaps.end(), GetPtr);
896 privateUpdateExitBlocksForClonedLoop(ExitBlocks, MapBegin, MapEnd, DT);
904 for (
const auto &Update : Updates) {
905 if (Update.getKind() == DT.
Insert)
906 InsertUpdates.
push_back({DT.
Insert, Update.getFrom(), Update.getTo()});
908 DeleteUpdates.
push_back({DT.
Delete, Update.getFrom(), Update.getTo()});
909 RevDeleteUpdates.
push_back({DT.
Insert, Update.getFrom(), Update.getTo()});
913 if (!DeleteUpdates.
empty()) {
914 if (!InsertUpdates.
empty()) {
946 for (
auto &Update : DeleteUpdates)
965 return &*(--Defs->
end());
970 for (
auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
985 if (IDom->getBlock() != BB) {
986 BB = IDom->getBlock();
989 return MSSA->getLiveOnEntryDef();
992 assert(
Count == 1 && Pred &&
"Single predecessor expected.");
995 return MSSA->getLiveOnEntryDef();
1005 auto FindNearestCommonDominator =
1006 [&](
const SmallSetVector<BasicBlock *, 2> &BBSet) -> BasicBlock * {
1008 for (
auto *BB : BBSet)
1015 auto GetNoLongerDomBlocks =
1017 SmallVectorImpl<BasicBlock *> &BlocksPrevDom) {
1018 if (PrevIDom == CurrIDom)
1020 BlocksPrevDom.push_back(PrevIDom);
1022 while (BasicBlock *UpIDom =
1024 if (UpIDom == CurrIDom)
1026 BlocksPrevDom.push_back(UpIDom);
1046 SmallSetVector<BasicBlock *, 2>
Added;
1047 SmallSetVector<BasicBlock *, 2> Prev;
1049 SmallDenseMap<BasicBlock *, PredInfo> PredMap;
1051 for (
const auto &
Edge : Updates) {
1053 auto &AddedBlockSet = PredMap[BB].Added;
1058 SmallDenseMap<std::pair<BasicBlock *, BasicBlock *>,
int> EdgeCountMap;
1059 SmallPtrSet<BasicBlock *, 2> NewBlocks;
1060 for (
auto &BBPredPair : PredMap) {
1061 auto *BB = BBPredPair.first;
1062 const auto &AddedBlockSet = BBPredPair.second.Added;
1063 auto &PrevBlockSet = BBPredPair.second.Prev;
1064 for (
auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
1065 if (!AddedBlockSet.count(Pi))
1066 PrevBlockSet.insert(Pi);
1067 EdgeCountMap[{Pi, BB}]++;
1070 if (PrevBlockSet.empty()) {
1071 assert(
pred_size(BB) == AddedBlockSet.size() &&
"Duplicate edges added.");
1074 <<
"Adding a predecessor to a block with no predecessors. "
1075 "This must be an edge added to a new, likely cloned, block. "
1076 "Its memory accesses must be already correct, assuming completed "
1077 "via the updateExitBlocksForClonedLoop API. "
1078 "Assert a single such edge is added so no phi addition or "
1079 "additional processing is required.\n");
1080 assert(AddedBlockSet.size() == 1 &&
1081 "Can only handle adding one predecessor to a new block.");
1088 for (
auto *BB : NewBlocks)
1091 SmallVector<BasicBlock *, 16> BlocksWithDefsToReplace;
1096 for (
const auto &
Edge : Updates) {
1098 if (PredMap.count(BB) && !MSSA->getMemoryAccess(BB))
1099 InsertedPhis.
push_back(MSSA->createMemoryPhi(BB));
1103 for (
auto &BBPredPair : PredMap) {
1104 auto *BB = BBPredPair.first;
1105 const auto &PrevBlockSet = BBPredPair.second.Prev;
1106 const auto &AddedBlockSet = BBPredPair.second.Added;
1107 assert(!PrevBlockSet.empty() &&
1108 "At least one previous predecessor must exist.");
1116 SmallDenseMap<BasicBlock *, MemoryAccess *> LastDefAddedPred;
1117 for (
auto *AddedPred : AddedBlockSet) {
1118 auto *DefPn = GetLastDef(AddedPred);
1119 assert(DefPn !=
nullptr &&
"Unable to find last definition.");
1120 LastDefAddedPred[AddedPred] = DefPn;
1123 MemoryPhi *NewPhi = MSSA->getMemoryAccess(BB);
1127 for (
auto *Pred : AddedBlockSet) {
1128 auto *LastDefForPred = LastDefAddedPred[Pred];
1129 for (
int I = 0,
E = EdgeCountMap[{Pred, BB}];
I <
E; ++
I)
1135 auto *
P1 = *PrevBlockSet.begin();
1136 MemoryAccess *DefP1 = GetLastDef(P1);
1140 bool InsertPhi =
false;
1141 for (
auto LastDefPredPair : LastDefAddedPred)
1142 if (DefP1 != LastDefPredPair.second) {
1158 for (
auto *Pred : AddedBlockSet) {
1159 auto *LastDefForPred = LastDefAddedPred[Pred];
1160 for (
int I = 0,
E = EdgeCountMap[{Pred, BB}];
I <
E; ++
I)
1163 for (
auto *Pred : PrevBlockSet)
1164 for (
int I = 0,
E = EdgeCountMap[{Pred, BB}];
I <
E; ++
I)
1171 BasicBlock *PrevIDom = FindNearestCommonDominator(PrevBlockSet);
1172 assert(PrevIDom &&
"Previous IDom should exists");
1174 assert(NewIDom &&
"BB should have a new valid idom");
1176 "New idom should dominate old idom");
1177 GetNoLongerDomBlocks(PrevIDom, NewIDom, BlocksWithDefsToReplace);
1180 tryRemoveTrivialPhis(InsertedPhis);
1183 SmallVector<BasicBlock *, 8> BlocksToProcess;
1184 for (
auto &VH : InsertedPhis)
1186 BlocksToProcess.
push_back(MPhi->getBlock());
1190 if (!BlocksToProcess.
empty()) {
1194 IDFs.setDefiningBlocks(DefiningBlocks);
1195 IDFs.calculate(IDFBlocks);
1197 SmallSetVector<MemoryPhi *, 4> PhisToFill;
1199 for (
auto *BBIDF : IDFBlocks)
1200 if (!MSSA->getMemoryAccess(BBIDF)) {
1201 auto *IDFPhi = MSSA->createMemoryPhi(BBIDF);
1202 InsertedPhis.push_back(IDFPhi);
1203 PhisToFill.
insert(IDFPhi);
1206 for (
auto *BBIDF : IDFBlocks) {
1207 auto *IDFPhi = MSSA->getMemoryAccess(BBIDF);
1208 assert(IDFPhi &&
"Phi must exist");
1209 if (!PhisToFill.
count(IDFPhi)) {
1212 for (
unsigned I = 0,
E = IDFPhi->getNumIncomingValues();
I <
E; ++
I)
1213 IDFPhi->setIncomingValue(
I, GetLastDef(IDFPhi->getIncomingBlock(
I)));
1215 for (
auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BBIDF))
1216 IDFPhi->addIncoming(GetLastDef(Pi), Pi);
1224 for (
auto *BlockWithDefsToReplace : BlocksWithDefsToReplace) {
1225 if (
auto DefsList = MSSA->getBlockDefs(BlockWithDefsToReplace)) {
1226 for (
auto &DefToReplaceUses : *DefsList) {
1227 BasicBlock *DominatingBlock = DefToReplaceUses.getBlock();
1234 BasicBlock *DominatedBlock = UsrPhi->getIncomingBlock(U);
1235 if (!DT.
dominates(DominatingBlock, DominatedBlock))
1236 U.set(GetLastDef(DominatedBlock));
1239 if (!DT.
dominates(DominatingBlock, DominatedBlock)) {
1240 if (
auto *DomBlPhi = MSSA->getMemoryAccess(DominatedBlock))
1244 assert(IDom &&
"Block must have a valid IDom.");
1245 U.set(GetLastDef(IDom->getBlock()));
1252 for (
auto *Usr : ResetOptimized)
1253 Usr->resetOptimized();
1257 tryRemoveTrivialPhis(InsertedPhis);
1261template <
class WhereType>
1265 for (
auto *U : What->
users())
1267 NonOptPhis.insert(PhiUser);
1273 MSSA->moveTo(What, BB, Where);
1299 return moveTo(What, BB, Where);
1301 if (
auto *Where = MSSA->getMemoryAccess(BB->
getTerminator()))
1315 assert(Start->getParent() == To &&
"Incorrect Start instruction");
1323 auto NextIt = ++MUD->getIterator();
1337 auto *Defs = MSSA->getBlockDefs(From);
1338 if (Defs && !Defs->
empty())
1340 tryRemoveTrivialPhi(Phi);
1346 assert(MSSA->getBlockAccesses(To) ==
nullptr &&
1347 "To block is expected to be free of MemoryAccesses.");
1348 moveAllAccesses(From, To, Start);
1350 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
1351 MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
1357 "From block is expected to have a single predecessor (To).");
1358 moveAllAccesses(From, To, Start);
1360 if (
MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
1361 MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
1366 bool IdenticalEdgesWereMerged) {
1367 assert(!MSSA->getBlockAccesses(New) &&
1368 "Access list should be null for a new block.");
1369 MemoryPhi *Phi = MSSA->getMemoryAccess(Old);
1374 "Should have moved all predecessors.");
1377 assert(!Preds.
empty() &&
"Must be moving at least one predecessor to the "
1378 "new immediate predecessor.");
1379 MemoryPhi *NewPhi = MSSA->createMemoryPhi(New);
1383 if (!IdenticalEdgesWereMerged)
1385 "If identical edges were not merged, we cannot have duplicate "
1386 "blocks in the predecessors");
1390 if (!IdenticalEdgesWereMerged)
1396 Phi->addIncoming(NewPhi, New);
1397 tryRemoveTrivialPhi(NewPhi);
1402 assert(!MSSA->isLiveOnEntryDef(MA) &&
1403 "Trying to remove the live on entry def");
1415 "We can't delete this memory phi");
1437 assert(NewDefTarget != MA &&
"Going into an infinite loop");
1441 MUD->resetOptimized();
1445 U.set(NewDefTarget);
1451 MSSA->removeFromLookups(MA);
1452 MSSA->removeFromLists(MA);
1455 if (!PhisToCheck.
empty()) {
1458 PhisToCheck.
clear();
1460 unsigned PhisSize = PhisToOptimize.
size();
1461 while (PhisSize-- > 0)
1464 tryRemoveTrivialPhi(MP);
1473 assert(TI &&
"Basic block expected to have a terminator instruction");
1475 if (!DeadBlocks.
count(Succ))
1476 if (
MemoryPhi *MP = MSSA->getMemoryAccess(Succ)) {
1477 MP->unorderedDeleteIncomingBlock(BB);
1478 tryRemoveTrivialPhi(MP);
1492 MSSA->removeFromLookups(&MA);
1493 MSSA->removeFromLists(&MA);
1499 for (
const auto &VH : UpdatedPHIs)
1501 tryRemoveTrivialPhi(MPhi);
1507 auto BBI =
I->getIterator(), BBE = BB->
end();
1517 MPhi->unorderedDeleteIncomingBlock(BB);
1522 tryRemoveTrivialPhis(UpdatedPHIs);
1529 I, Definition,
nullptr, CreationMustSucceed);
1531 MSSA->insertIntoListsForBlock(NewAccess, BB, Point);
1538 "New and old access must be in the same block");
1540 MSSA->insertIntoListsBefore(NewAccess, InsertPt->
getBlock(),
1548 "New and old access must be in the same block");
1550 MSSA->insertIntoListsBefore(NewAccess, InsertPt->
getBlock(),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks
static MemoryAccess * getNewDefiningAccessForClone(MemoryAccess *MA, const ValueToValueMapTy &VMap, PhiToDefMap &MPhiMap, MemorySSA *MSSA, function_ref< bool(BasicBlock *BB)> IsInClonedRegion)
static void setMemoryPhiValueForBlock(MemoryPhi *MP, const BasicBlock *BB, MemoryAccess *NewDef)
static MemoryAccess * onlySingleValue(MemoryPhi *MP)
If all arguments of a MemoryPHI are defined by the same incoming argument, return that argument.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
Remove Loads Into Fake Uses
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
This file defines the SmallPtrSet class.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static const uint32_t IV[8]
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
LLVM Basic Block Representation.
reverse_iterator rbegin()
LLVM_ABI bool hasNPredecessors(unsigned N) const
Return true if this block has exactly N predecessors.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DomTreeNodeBase * getIDom() const
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
void calculate(SmallVectorImpl< NodeTy * > &IDFBlocks)
Calculate iterated dominance frontiers.
void setDefiningBlocks(const SmallPtrSetImpl< NodeTy * > &Blocks)
Give the IDF calculator the set of blocks in which the value is defined.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
AllAccessType::reverse_self_iterator getReverseIterator()
DefsOnlyType::self_iterator getDefsIterator()
DefsOnlyType::reverse_self_iterator getReverseDefsIterator()
BasicBlock * getBlock() const
AllAccessType::self_iterator getIterator()
Get the iterators for the all access list and the defs only list We default to the all access list.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
Represents phi nodes for memory accesses.
void setIncomingValue(unsigned I, MemoryAccess *V)
iterator_range< block_iterator > blocks()
void addIncoming(MemoryAccess *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
LLVM_ABI MemoryUseOrDef * createMemoryAccessBefore(Instruction *I, MemoryAccess *Definition, MemoryUseOrDef *InsertPt)
Create a MemoryAccess in MemorySSA before an existing MemoryAccess.
LLVM_ABI void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
LLVM_ABI void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where)
LLVM_ABI void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
LLVM_ABI 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...
LLVM_ABI void changeToUnreachable(const Instruction *I)
Instruction I will be changed to an unreachable.
LLVM_ABI void removeDuplicatePhiEdgesBetween(const BasicBlock *From, const BasicBlock *To)
Update the MemoryPhi in To to have a single incoming edge from From, following a CFG change that repl...
LLVM_ABI void updatePhisWhenInsertingUniqueBackedgeBlock(BasicBlock *LoopHeader, BasicBlock *LoopPreheader, BasicBlock *BackedgeBlock)
Update MemorySSA when inserting a unique backedge block for a loop.
LLVM_ABI void insertUse(MemoryUse *Use, bool RenameUses=false)
LLVM_ABI void removeBlocks(const SmallSetVector< BasicBlock *, 8 > &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
LLVM_ABI void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was spliced into From and To.
LLVM_ABI MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point, bool CreationMustSucceed=true)
Create a MemoryAccess in MemorySSA at a specified point in a block.
LLVM_ABI void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
LLVM_ABI void applyInsertUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT)
Apply CFG insert updates, analogous with the DT edge updates.
LLVM_ABI MemoryUseOrDef * createMemoryAccessAfter(Instruction *I, MemoryAccess *Definition, MemoryAccess *InsertPt)
Create a MemoryAccess in MemorySSA after an existing MemoryAccess.
LLVM_ABI void updateForClonedBlockIntoPred(BasicBlock *BB, BasicBlock *P1, const ValueToValueMapTy &VM)
LLVM_ABI void applyUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT, bool UpdateDTFirst=false)
Apply CFG updates, analogous with the DT edge updates.
LLVM_ABI void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was merged into To.
LLVM_ABI void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
LLVM_ABI void wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, BasicBlock *New, ArrayRef< BasicBlock * > Preds, bool IdenticalEdgesWereMerged=true)
A new empty BasicBlock (New) now branches directly to Old.
LLVM_ABI void updateExitBlocksForClonedLoop(ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VMap, DominatorTree &DT)
Update phi nodes in exit block successors following cloning.
LLVM_ABI void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where)
Encapsulates MemorySSA, including all data associated with memory accesses.
simple_ilist< MemoryAccess, ilist_tag< MSSAHelpers::DefsOnlyTag > > DefsList
LLVM_ABI void moveTo(MemoryUseOrDef *What, BasicBlock *BB, AccessList::iterator Where)
DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
iplist< MemoryAccess, ilist_tag< MSSAHelpers::AllAccessTag > > AccessList
AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
InsertionPlace
Used in various insertion functions to specify whether we are talking about the beginning or end of a...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
MemoryAccess * getLiveOnEntryDef() const
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
Class that has the common methods + fields of memory uses/defs.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
void setDefiningAccess(MemoryAccess *DMA, bool Optimized=false)
Represents read-only accesses to memory.
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
iterator end()
Get an iterator to the end of the SetVector.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Value handle that tracks a Value across RAUW.
A Use represents the edge between a Value definition and its users.
void dropAllReferences()
Drop all references to operands.
unsigned getNumOperands() const
static LLVM_ABI void ValueIsRAUWd(Value *Old, Value *New)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
bool hasValueHandle() const
Return true if there is a value handle associated with this value.
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
bool empty() const
Check if the list is empty in constant time.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
SmallDenseMap< MemoryPhi *, MemoryAccess * > PhiToDefMap
auto pred_end(const MachineBasicBlock *BB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
constexpr from_range_t from_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto cast_or_null(const Y &Val)
auto pred_size(const MachineBasicBlock *BB)
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IDFCalculator< false > ForwardIDFCalculator
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
PredIterator< BasicBlock, Value::user_iterator > pred_iterator
OutputIt copy(R &&Range, OutputIt Out)
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.