LLVM: lib/Analysis/MemorySSAUpdater.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
22#include
23
24#define DEBUG_TYPE "memoryssa"
25using namespace llvm;
26
27
28
29
30
31
32
33
34
35
36MemoryAccess *MemorySSAUpdater::getPreviousDefRecursive(
39
40
41 auto Cached = CachedPreviousDef.find(BB);
42 if (Cached != CachedPreviousDef.end())
43 return Cached->second;
44
45
48
51
52 MemoryAccess *Result = getPreviousDefFromEnd(Pred, CachedPreviousDef);
53 CachedPreviousDef.insert({BB, Result});
54 return Result;
55 }
56
58
59
60
61 MemoryAccess *Result = MSSA->createMemoryPhi(BB);
62 CachedPreviousDef.insert({BB, Result});
63 return Result;
64 }
65
67
69
70
71
72
73 bool UniqueIncomingAccess = true;
77 auto *IncomingAccess = getPreviousDefFromEnd(Pred, CachedPreviousDef);
78 if (!SingleAccess)
79 SingleAccess = IncomingAccess;
80 else if (IncomingAccess != SingleAccess)
81 UniqueIncomingAccess = false;
83 } else
85 }
86
87
88
90
91
92 auto *Result = tryRemoveTrivialPhi(Phi, PhiOps);
93
94 if (Result == Phi && UniqueIncomingAccess && SingleAccess) {
95
96 if (Phi) {
97 assert(Phi->operands().empty() && "Expected empty Phi");
98 Phi->replaceAllUsesWith(SingleAccess);
100 }
101 Result = SingleAccess;
102 } else if (Result == Phi && !(UniqueIncomingAccess && SingleAccess)) {
103 if (!Phi)
104 Phi = MSSA->createMemoryPhi(BB);
105
106
107
108
109 if (Phi->getNumOperands() != 0) {
110
111 if (!std::equal(Phi->op_begin(), Phi->op_end(), PhiOps.begin())) {
112
115 }
116 } else {
117 unsigned i = 0;
119 Phi->addIncoming(&*PhiOps[i++], Pred);
120 InsertedPHIs.push_back(Phi);
121 }
122 Result = Phi;
123 }
124
125
127 CachedPreviousDef.insert({BB, Result});
128 return Result;
129 }
130 llvm_unreachable("Should have hit one of the three cases above");
131}
132
133
134
135
136
138 if (auto *LocalResult = getPreviousDefInBlock(MA))
139 return LocalResult;
140 DenseMap<BasicBlock *, TrackingVH> CachedPreviousDef;
141 return getPreviousDefRecursive(MA->getBlock(), CachedPreviousDef);
142}
143
144
145
146
148 auto *Defs = MSSA->getWritableBlockDefs(MA->getBlock());
149
150
151 if (Defs) {
152
155 ++Iter;
156 if (Iter != Defs->rend())
157 return &*Iter;
158 } else {
159
160 auto End = MSSA->getWritableBlockAccesses(MA->getBlock())->rend();
164
165 return nullptr;
166 }
167 }
168 return nullptr;
169}
170
171
172MemoryAccess *MemorySSAUpdater::getPreviousDefFromEnd(
175 auto *Defs = MSSA->getWritableBlockDefs(BB);
176
177 if (Defs) {
178 CachedPreviousDef.insert({BB, &*Defs->rbegin()});
179 return &*Defs->rbegin();
180 }
181
182 return getPreviousDefRecursive(BB, CachedPreviousDef);
183}
184
186 if (!Phi)
187 return nullptr;
188 TrackingVH Res(Phi);
190 std::copy(Phi->user_begin(), Phi->user_end(), std::back_inserter(Uses));
191 for (auto &U : Uses)
193 tryRemoveTrivialPhi(UsePhi);
194 return Res;
195}
196
197
198
199
200
201
203 assert(Phi && "Can only remove concrete Phi.");
204 auto OperRange = Phi->operands();
205 return tryRemoveTrivialPhi(Phi, OperRange);
206}
207template
209 RangeType &Operands) {
210
211 if (NonOptPhis.count(Phi))
212 return Phi;
213
214
215 MemoryAccess *Same = nullptr;
216 for (auto &Op : Operands) {
217
218 if (Op == Phi || Op == Same)
219 continue;
220
221 if (Same)
222 return Phi;
224 }
225
226 if (Same == nullptr)
227 return MSSA->getLiveOnEntryDef();
228 if (Phi) {
229 Phi->replaceAllUsesWith(Same);
231 }
232
233
234
235 return recursePhi(Same);
236}
237
239 VisitedBlocks.clear();
240 InsertedPHIs.clear();
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256 if (!RenameUses && !InsertedPHIs.empty()) {
257 auto *Defs = MSSA->getBlockDefs(MU->getBlock());
258 (void)Defs;
259 assert((!Defs || (++Defs->begin() == Defs->end())) &&
260 "Block may have only a Phi or no defs");
261 }
262
263 if (RenameUses && InsertedPHIs.size()) {
266
267 if (auto *Defs = MSSA->getWritableBlockDefs(StartBlock)) {
269
270
272 FirstDef = MD->getDefiningAccess();
273
274 MSSA->renamePass(MU->getBlock(), FirstDef, Visited);
275 }
276
277
278 for (auto &MP : InsertedPHIs)
280 MSSA->renamePass(Phi->getBlock(), nullptr, Visited);
281 }
282}
283
284
287
288
290 assert(i != -1 && "Should have found the basic block in the phi");
291
292
294 if (BlockBB != BB)
295 break;
297 ++i;
298 }
299}
300
301
302
303
304
305
306
308
309 if (!MSSA->DT->isReachableFromEntry(MD->getBlock())) {
311 return;
312 }
313
314 VisitedBlocks.clear();
315 InsertedPHIs.clear();
316
317
318 MemoryAccess *DefBefore = getPreviousDef(MD);
319 bool DefBeforeSameBlock = false;
323 DefBeforeSameBlock = true;
324
325
326
327
328
329 if (DefBeforeSameBlock) {
331
332
333 User *Usr = U.getUser();
335
336
337 });
338 }
339
340
342
344
346
347
348 unsigned NewPhiIndex = InsertedPHIs.size();
349 if (!DefBeforeSameBlock) {
350
351
352
353
354
355
356
357
358
359
360
361
362
363
365
366
367
368
369
371 for (const auto &VH : InsertedPHIs)
373 DefiningBlocks.insert(RealPHI->getBlock());
379 for (auto *BBIDF : IDFBlocks) {
380 auto *MPhi = MSSA->getMemoryAccess(BBIDF);
381 if (!MPhi) {
382 MPhi = MSSA->createMemoryPhi(BBIDF);
384 } else {
385 ExistingPhis.insert(MPhi);
386 }
387
388
389
390
391
392
393 NonOptPhis.insert(MPhi);
394 }
395 for (auto &MPhi : NewInsertedPHIs) {
396 auto *BBIDF = MPhi->getBlock();
399 MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), Pred);
400 }
401 }
402
403
404
405 NewPhiIndex = InsertedPHIs.size();
406 for (auto &MPhi : NewInsertedPHIs) {
407 InsertedPHIs.push_back(&*MPhi);
409 }
410
412 }
413
414
415 unsigned NewPhiIndexEnd = InsertedPHIs.size();
416 fixupDefs(FixupList);
417 assert(NewPhiIndexEnd == InsertedPHIs.size() &&
418 "Should not insert new phis during fixupDefs()");
419
420
421 unsigned NewPhiSize = NewPhiIndexEnd - NewPhiIndex;
422 if (NewPhiSize)
423 tryRemoveTrivialPhis(ArrayRef(&InsertedPHIs[NewPhiIndex], NewPhiSize));
424
425
426
428 if (RenameUses) {
430
431
432 MemoryAccess *FirstDef = &*MSSA->getWritableBlockDefs(StartBlock)->begin();
433
434
437
438 MSSA->renamePass(MD->getBlock(), FirstDef, Visited);
439
440
441 for (auto &MP : InsertedPHIs) {
443 if (Phi)
444 MSSA->renamePass(Phi->getBlock(), nullptr, Visited);
445 }
446
447
448 for (const auto &MP : ExistingPhis) {
450 if (Phi)
451 MSSA->renamePass(Phi->getBlock(), nullptr, Visited);
452 }
453 }
454}
455
459 for (const auto &Var : Vars) {
461 if (!NewDef)
462 continue;
463
466
467
469 NonOptPhis.erase(Phi);
470
471
472 if (++DefIter != Defs->end()) {
474 continue;
475 }
476
477
478
479
483 else
485 }
486
487 while (!Worklist.empty()) {
489
490
491 if (auto *Defs = MSSA->getWritableBlockDefs(FixupBlock)) {
492 auto *FirstDef = &*Defs->begin();
493
495 "Should have already handled phi nodes!");
496
497
498 assert(MSSA->dominates(NewDef, FirstDef) &&
499 "Should have dominated the new access");
500
502 continue;
503 }
504
505 for (const auto *S : successors(FixupBlock)) {
506
507
508 if (auto *MP = MSSA->getMemoryAccess(S))
510 else {
511
512
513 if (!Seen.insert(S).second)
514 continue;
516 }
517 }
518 }
519 }
520}
521
523 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(To)) {
524 MPhi->unorderedDeleteIncomingBlock(From);
525 tryRemoveTrivialPhi(MPhi);
526 }
527}
528
531 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(To)) {
532 bool Found = false;
534 if (From != B)
535 return false;
536 if (Found)
537 return true;
538 Found = true;
539 return false;
540 });
541 tryRemoveTrivialPhi(MPhi);
542 }
543}
544
545
546
549
550 for (auto &Arg : MP->operands()) {
551 if (!MA)
553 else if (MA != Arg)
554 return nullptr;
555 }
556 return MA;
557}
558
565 return DefMUD;
566
567
568 Instruction *DefMUDI = DefMUD->getMemoryInst();
569 assert(DefMUDI && "Found MemoryUseOrDef with no Instruction.");
570 if (!IsInClonedRegion(DefMUDI->getParent()))
571 return DefMUD;
572
574 InsnDefining = NewDefMUDI ? MSSA->getMemoryAccess(NewDefMUDI) : nullptr;
576
578 DefMUD->getDefiningAccess(), VMap, MPhiMap, MSSA, IsInClonedRegion);
579 }
580 } else {
583 InsnDefining = NewDefPhi;
584 }
585 assert(InsnDefining && "Defining instruction cannot be nullptr.");
586 return InsnDefining;
587}
588
589void MemorySSAUpdater::cloneUsesAndDefs(
592 bool CloneWasSimplified) {
594 if (!Acc)
595 return;
596 for (const MemoryAccess &MA : *Acc) {
598 Instruction *Insn = MUD->getMemoryInst();
599
600
601
602
603
604
605
606 if (Instruction *NewInsn =
608 MemoryAccess *NewUseOrDef = MSSA->createDefinedAccess(
609 NewInsn,
611 MPhiMap, MSSA, IsInClonedRegion),
612 CloneWasSimplified ? nullptr : MUD,
613 false);
614 if (NewUseOrDef)
615 MSSA->insertIntoListsForBlock(NewUseOrDef, NewBB, MemorySSA::End);
616 }
617 }
618 }
619}
620
623 auto *MPhi = MSSA->getMemoryAccess(Header);
624 if (!MPhi)
625 return;
626
627
628
629 auto *NewMPhi = MSSA->createMemoryPhi(BEBlock);
630 bool HasUniqueIncomingValue = true;
632 for (unsigned I = 0, E = MPhi->getNumIncomingValues(); I != E; ++I) {
633 BasicBlock *IBB = MPhi->getIncomingBlock(I);
635 if (IBB != Preheader) {
636 NewMPhi->addIncoming(IV, IBB);
637 if (HasUniqueIncomingValue) {
638 if (!UniqueValue)
639 UniqueValue = IV;
640 else if (UniqueValue != IV)
641 HasUniqueIncomingValue = false;
642 }
643 }
644 }
645
646
647
648 auto *AccFromPreheader = MPhi->getIncomingValueForBlock(Preheader);
649 MPhi->setIncomingValue(0, AccFromPreheader);
650 MPhi->setIncomingBlock(0, Preheader);
651 for (unsigned I = MPhi->getNumIncomingValues() - 1; I >= 1; --I)
652 MPhi->unorderedDeleteIncoming(I);
653 MPhi->addIncoming(NewMPhi, BEBlock);
654
655
656
657 tryRemoveTrivialPhi(NewMPhi);
658}
659
663 bool IgnoreIncomingWithNoClones) {
666
667 auto IsInClonedRegion = [&](BasicBlock *BB) { return Blocks.contains(BB); };
668
671 assert(Phi && NewPhi && "Invalid Phi nodes.");
672 BasicBlock *NewPhiBB = NewPhi->getBlock();
675 for (unsigned It = 0, E = Phi->getNumIncomingValues(); It < E; ++It) {
676 MemoryAccess *IncomingAccess = Phi->getIncomingValue(It);
677 BasicBlock *IncBB = Phi->getIncomingBlock(It);
678
680 IncBB = NewIncBB;
681 else if (IgnoreIncomingWithNoClones)
682 continue;
683
684
685
686
687
688 if (!NewPhiBBPreds.count(IncBB))
689 continue;
690
691
693 MPhiMap, MSSA,
694 IsInClonedRegion),
695 IncBB);
696 }
698 MPhiMap[Phi] = SingleAccess;
700 }
701 };
702
705 if (!NewBlock)
706 return;
707
708 assert(!MSSA->getWritableBlockAccesses(NewBlock) &&
709 "Cloned block should have no accesses");
710
711
712 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(BB)) {
713 MemoryPhi *NewPhi = MSSA->createMemoryPhi(NewBlock);
714 MPhiMap[MPhi] = NewPhi;
715 }
716
717 cloneUsesAndDefs(BB, NewBlock, VMap, MPhiMap, IsInClonedRegion);
718 };
719
720 for (auto *BB : Blocks)
722
723 for (auto *BB : Blocks)
724 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(BB))
727}
728
731
732
733
734
735
736
737
738
740 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(BB))
741 MPhiMap[MPhi] = MPhi->getIncomingValueForBlock(P1);
742 cloneUsesAndDefs(
743 BB, P1, VM, MPhiMap, [&](BasicBlock *CheckBB) { return BB == CheckBB; },
744 true);
745}
746
747template
748void MemorySSAUpdater::privateUpdateExitBlocksForClonedLoop(
752
753 for (auto *Exit : ExitBlocks)
758 }
760}
761
766 privateUpdateExitBlocksForClonedLoop(ExitBlocks, std::begin(Arr),
767 std::end(Arr), DT);
768}
769
773 auto GetPtr = [&](const std::unique_ptr &I) {
774 return I.get();
775 };
776 using MappedIteratorType =
778 decltype(GetPtr)>;
779 auto MapBegin = MappedIteratorType(VMaps.begin(), GetPtr);
780 auto MapEnd = MappedIteratorType(VMaps.end(), GetPtr);
781 privateUpdateExitBlocksForClonedLoop(ExitBlocks, MapBegin, MapEnd, DT);
782}
783
789 for (const auto &Update : Updates) {
790 if (Update.getKind() == DT.Insert)
791 InsertUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
792 else {
793 DeleteUpdates.push_back({DT.Delete, Update.getFrom(), Update.getTo()});
794 RevDeleteUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
795 }
796 }
797
798 if (!DeleteUpdates.empty()) {
799 if (!InsertUpdates.empty()) {
800 if (!UpdateDT) {
802
803
805 } else {
806
808 }
809
810
811
812
813
816
817
819 } else {
820 if (UpdateDT)
822 }
823 } else {
824 if (UpdateDT)
828 }
829
830
831 for (auto &Update : DeleteUpdates)
832 removeEdge(Update.getFrom(), Update.getTo());
833}
834
840
844
846 while (true) {
848
849 if (Defs)
850 return &*(--Defs->end());
851
852
853 unsigned Count = 0;
855 for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
856 Pred = Pi;
859 break;
860 }
861
862
863 if (Count != 1) {
864
865
866
870 if (IDom->getBlock() != BB) {
871 BB = IDom->getBlock();
872 continue;
873 }
874 return MSSA->getLiveOnEntryDef();
875 } else {
876
877 assert(Count == 1 && Pred && "Single predecessor expected.");
878
880 return MSSA->getLiveOnEntryDef();
881 BB = Pred;
882 }
883 };
885 };
886
887
888
889
890 auto FindNearestCommonDominator =
891 [&](const SmallSetVector<BasicBlock *, 2> &BBSet) -> BasicBlock * {
892 BasicBlock *PrevIDom = *BBSet.begin();
893 for (auto *BB : BBSet)
895 return PrevIDom;
896 };
897
898
899
900 auto GetNoLongerDomBlocks =
902 SmallVectorImpl<BasicBlock *> &BlocksPrevDom) {
903 if (PrevIDom == CurrIDom)
904 return;
905 BlocksPrevDom.push_back(PrevIDom);
907 while (BasicBlock *UpIDom =
909 if (UpIDom == CurrIDom)
910 break;
911 BlocksPrevDom.push_back(UpIDom);
912 NextIDom = UpIDom;
913 }
914 };
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930 struct PredInfo {
931 SmallSetVector<BasicBlock *, 2> Added;
932 SmallSetVector<BasicBlock *, 2> Prev;
933 };
934 SmallDenseMap<BasicBlock *, PredInfo> PredMap;
935
936 for (const auto &Edge : Updates) {
938 auto &AddedBlockSet = PredMap[BB].Added;
939 AddedBlockSet.insert(Edge.getFrom());
940 }
941
942
943 SmallDenseMap<std::pair<BasicBlock *, BasicBlock *>, int> EdgeCountMap;
944 SmallPtrSet<BasicBlock *, 2> NewBlocks;
945 for (auto &BBPredPair : PredMap) {
946 auto *BB = BBPredPair.first;
947 const auto &AddedBlockSet = BBPredPair.second.Added;
948 auto &PrevBlockSet = BBPredPair.second.Prev;
949 for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) {
950 if (!AddedBlockSet.count(Pi))
951 PrevBlockSet.insert(Pi);
952 EdgeCountMap[{Pi, BB}]++;
953 }
954
955 if (PrevBlockSet.empty()) {
956 assert(pred_size(BB) == AddedBlockSet.size() && "Duplicate edges added.");
959 << "Adding a predecessor to a block with no predecessors. "
960 "This must be an edge added to a new, likely cloned, block. "
961 "Its memory accesses must be already correct, assuming completed "
962 "via the updateExitBlocksForClonedLoop API. "
963 "Assert a single such edge is added so no phi addition or "
964 "additional processing is required.\n");
965 assert(AddedBlockSet.size() == 1 &&
966 "Can only handle adding one predecessor to a new block.");
967
968
969 NewBlocks.insert(BB);
970 }
971 }
972
973 for (auto *BB : NewBlocks)
974 PredMap.erase(BB);
975
976 SmallVector<BasicBlock *, 16> BlocksWithDefsToReplace;
978
979
980
981 for (const auto &Edge : Updates) {
983 if (PredMap.count(BB) && !MSSA->getMemoryAccess(BB))
984 InsertedPhis.push_back(MSSA->createMemoryPhi(BB));
985 }
986
987
988 for (auto &BBPredPair : PredMap) {
989 auto *BB = BBPredPair.first;
990 const auto &PrevBlockSet = BBPredPair.second.Prev;
991 const auto &AddedBlockSet = BBPredPair.second.Added;
992 assert(!PrevBlockSet.empty() &&
993 "At least one previous predecessor must exist.");
994
995
996
997
998
999
1000
1001 SmallDenseMap<BasicBlock *, MemoryAccess *> LastDefAddedPred;
1002 for (auto *AddedPred : AddedBlockSet) {
1003 auto *DefPn = GetLastDef(AddedPred);
1004 assert(DefPn != nullptr && "Unable to find last definition.");
1005 LastDefAddedPred[AddedPred] = DefPn;
1006 }
1007
1008 MemoryPhi *NewPhi = MSSA->getMemoryAccess(BB);
1009
1010
1012 for (auto *Pred : AddedBlockSet) {
1013 auto *LastDefForPred = LastDefAddedPred[Pred];
1014 for (int I = 0, E = EdgeCountMap[{Pred, BB}]; I < E; ++I)
1015 NewPhi->addIncoming(LastDefForPred, Pred);
1016 }
1017 } else {
1018
1019
1020 auto *P1 = *PrevBlockSet.begin();
1021 MemoryAccess *DefP1 = GetLastDef(P1);
1022
1023
1024
1025 bool InsertPhi = false;
1026 for (auto LastDefPredPair : LastDefAddedPred)
1027 if (DefP1 != LastDefPredPair.second) {
1028 InsertPhi = true;
1029 break;
1030 }
1031 if (!InsertPhi) {
1032
1033
1034
1037 continue;
1038 }
1039
1040
1041
1042
1043 for (auto *Pred : AddedBlockSet) {
1044 auto *LastDefForPred = LastDefAddedPred[Pred];
1045 for (int I = 0, E = EdgeCountMap[{Pred, BB}]; I < E; ++I)
1046 NewPhi->addIncoming(LastDefForPred, Pred);
1047 }
1048 for (auto *Pred : PrevBlockSet)
1049 for (int I = 0, E = EdgeCountMap[{Pred, BB}]; I < E; ++I)
1051 }
1052
1053
1054
1056 BasicBlock *PrevIDom = FindNearestCommonDominator(PrevBlockSet);
1057 assert(PrevIDom && "Previous IDom should exists");
1059 assert(NewIDom && "BB should have a new valid idom");
1061 "New idom should dominate old idom");
1062 GetNoLongerDomBlocks(PrevIDom, NewIDom, BlocksWithDefsToReplace);
1063 }
1064
1065 tryRemoveTrivialPhis(InsertedPhis);
1066
1067
1068 SmallVector<BasicBlock *, 8> BlocksToProcess;
1069 for (auto &VH : InsertedPhis)
1071 BlocksToProcess.push_back(MPhi->getBlock());
1072
1073
1075 if (!BlocksToProcess.empty()) {
1077 SmallPtrSet<BasicBlock *, 16> DefiningBlocks(llvm::from_range,
1078 BlocksToProcess);
1079 IDFs.setDefiningBlocks(DefiningBlocks);
1080 IDFs.calculate(IDFBlocks);
1081
1082 SmallSetVector<MemoryPhi *, 4> PhisToFill;
1083
1084 for (auto *BBIDF : IDFBlocks)
1085 if (!MSSA->getMemoryAccess(BBIDF)) {
1086 auto *IDFPhi = MSSA->createMemoryPhi(BBIDF);
1087 InsertedPhis.push_back(IDFPhi);
1088 PhisToFill.insert(IDFPhi);
1089 }
1090
1091 for (auto *BBIDF : IDFBlocks) {
1092 auto *IDFPhi = MSSA->getMemoryAccess(BBIDF);
1093 assert(IDFPhi && "Phi must exist");
1094 if (!PhisToFill.count(IDFPhi)) {
1095
1096
1097 for (unsigned I = 0, E = IDFPhi->getNumIncomingValues(); I < E; ++I)
1098 IDFPhi->setIncomingValue(I, GetLastDef(IDFPhi->getIncomingBlock(I)));
1099 } else {
1100 for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BBIDF))
1101 IDFPhi->addIncoming(GetLastDef(Pi), Pi);
1102 }
1103 }
1104 }
1105
1106
1107
1108
1109 for (auto *BlockWithDefsToReplace : BlocksWithDefsToReplace) {
1110 if (auto DefsList = MSSA->getWritableBlockDefs(BlockWithDefsToReplace)) {
1111 for (auto &DefToReplaceUses : *DefsList) {
1112 BasicBlock *DominatingBlock = DefToReplaceUses.getBlock();
1113
1114
1119 BasicBlock *DominatedBlock = UsrPhi->getIncomingBlock(U);
1120 if (!DT.dominates(DominatingBlock, DominatedBlock))
1121 U.set(GetLastDef(DominatedBlock));
1122 } else {
1124 if (!DT.dominates(DominatingBlock, DominatedBlock)) {
1125 if (auto *DomBlPhi = MSSA->getMemoryAccess(DominatedBlock))
1126 U.set(DomBlPhi);
1127 else {
1129 assert(IDom && "Block must have a valid IDom.");
1130 U.set(GetLastDef(IDom->getBlock()));
1131 }
1133 }
1134 }
1135 }
1136
1137 for (auto *Usr : ResetOptimized)
1138 Usr->resetOptimized();
1139 }
1140 }
1141 }
1142 tryRemoveTrivialPhis(InsertedPhis);
1143}
1144
1145
1146template
1148 WhereType Where) {
1149
1150 for (auto *U : What->users())
1152 NonOptPhis.insert(PhiUser);
1153
1154
1156
1157
1158 MSSA->moveTo(What, BB, Where);
1159
1160
1162 insertDef(MD, true);
1163 else
1165
1166
1167
1168 NonOptPhis.clear();
1169}
1170
1171
1175
1176
1180
1184 return moveTo(What, BB, Where);
1185
1186 if (auto *Where = MSSA->getMemoryAccess(BB->getTerminator()))
1188 else
1190}
1191
1192
1195
1197 if (!Accs)
1198 return;
1199
1200 assert(Start->getParent() == To && "Incorrect Start instruction");
1204 break;
1205 if (FirstInNew) {
1207 do {
1208 auto NextIt = ++MUD->getIterator();
1209 MemoryUseOrDef *NextMUD = (!Accs || NextIt == Accs->end())
1210 ? nullptr
1213
1214
1216 MUD = NextMUD;
1217 } while (MUD);
1218 }
1219
1220
1221
1222 auto *Defs = MSSA->getWritableBlockDefs(From);
1223 if (Defs && !Defs->empty())
1225 tryRemoveTrivialPhi(Phi);
1226}
1227
1231 assert(MSSA->getBlockAccesses(To) == nullptr &&
1232 "To block is expected to be free of MemoryAccesses.");
1233 moveAllAccesses(From, To, Start);
1235 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
1236 MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
1237}
1238
1242 "From block is expected to have a single predecessor (To).");
1243 moveAllAccesses(From, To, Start);
1245 if (MemoryPhi *MPhi = MSSA->getMemoryAccess(Succ))
1246 MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To);
1247}
1248
1251 bool IdenticalEdgesWereMerged) {
1252 assert(!MSSA->getWritableBlockAccesses(New) &&
1253 "Access list should be null for a new block.");
1254 MemoryPhi *Phi = MSSA->getMemoryAccess(Old);
1255 if (!Phi)
1256 return;
1259 "Should have moved all predecessors.");
1261 } else {
1262 assert(!Preds.empty() && "Must be moving at least one predecessor to the "
1263 "new immediate predecessor.");
1264 MemoryPhi *NewPhi = MSSA->createMemoryPhi(New);
1266
1267
1268 if (!IdenticalEdgesWereMerged)
1270 "If identical edges were not merged, we cannot have duplicate "
1271 "blocks in the predecessors");
1275 if (!IdenticalEdgesWereMerged)
1277 return true;
1278 }
1279 return false;
1280 });
1281 Phi->addIncoming(NewPhi, New);
1282 tryRemoveTrivialPhi(NewPhi);
1283 }
1284}
1285
1287 assert(!MSSA->isLiveOnEntryDef(MA) &&
1288 "Trying to remove the live on entry def");
1289
1290
1293
1294
1295
1296
1297
1300 "We can't delete this memory phi");
1301 } else {
1303 }
1304
1306
1307
1309
1310
1311
1312
1313
1314
1315
1316
1319
1320
1321
1322 assert(NewDefTarget != MA && "Going into an infinite loop");
1326 MUD->resetOptimized();
1327 if (OptimizePhis)
1329 PhisToCheck.insert(MP);
1330 U.set(NewDefTarget);
1331 }
1332 }
1333
1334
1335
1336 MSSA->removeFromLookups(MA);
1337 MSSA->removeFromLists(MA);
1338
1339
1340 if (!PhisToCheck.empty()) {
1342 PhisToCheck.end()};
1343 PhisToCheck.clear();
1344
1345 unsigned PhisSize = PhisToOptimize.size();
1346 while (PhisSize-- > 0)
1349 tryRemoveTrivialPhi(MP);
1350 }
1351}
1352
1355
1358 assert(TI && "Basic block expected to have a terminator instruction");
1360 if (!DeadBlocks.count(Succ))
1361 if (MemoryPhi *MP = MSSA->getMemoryAccess(Succ)) {
1362 MP->unorderedDeleteIncomingBlock(BB);
1363 tryRemoveTrivialPhi(MP);
1364 }
1365
1369 }
1370
1371
1374 if (!Acc)
1375 continue;
1377 MSSA->removeFromLookups(&MA);
1378 MSSA->removeFromLists(&MA);
1379 }
1380 }
1381}
1382
1383void MemorySSAUpdater::tryRemoveTrivialPhis(ArrayRef UpdatedPHIs) {
1384 for (const auto &VH : UpdatedPHIs)
1386 tryRemoveTrivialPhi(MPhi);
1387}
1388
1391
1392 auto BBI = I->getIterator(), BBE = BB->end();
1393
1394
1395 while (BBI != BBE)
1397
1402 MPhi->unorderedDeleteIncomingBlock(BB);
1404 }
1405 }
1406
1407 tryRemoveTrivialPhis(UpdatedPHIs);
1408}
1409
1413 MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(
1414 I, Definition, nullptr, CreationMustSucceed);
1415 if (NewAccess)
1416 MSSA->insertIntoListsForBlock(NewAccess, BB, Point);
1417 return NewAccess;
1418}
1419
1423 "New and old access must be in the same block");
1424 MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(I, Definition);
1425 MSSA->insertIntoListsBefore(NewAccess, InsertPt->getBlock(),
1427 return NewAccess;
1428}
1429
1433 "New and old access must be in the same block");
1434 MemoryUseOrDef *NewAccess = MSSA->createDefinedAccess(I, Definition);
1435 MSSA->insertIntoListsBefore(NewAccess, InsertPt->getBlock(),
1437 return NewAccess;
1438}
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)
Definition MemorySSAUpdater.cpp:559
static void setMemoryPhiValueForBlock(MemoryPhi *MP, const BasicBlock *BB, MemoryAccess *NewDef)
Definition MemorySSAUpdater.cpp:285
static MemoryAccess * onlySingleValue(MemoryPhi *MP)
If all arguments of a MemoryPHI are defined by the same incoming argument, return that argument.
Definition MemorySSAUpdater.cpp:547
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]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - 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 if the block is well formed or null if the block is not well forme...
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...
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.
Definition MemorySSAUpdater.cpp:1420
LLVM_ABI void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
Definition MemorySSAUpdater.cpp:307
LLVM_ABI void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where)
Definition MemorySSAUpdater.cpp:1177
LLVM_ABI void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
Definition MemorySSAUpdater.cpp:522
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...
Definition MemorySSAUpdater.cpp:660
LLVM_ABI void changeToUnreachable(const Instruction *I)
Instruction I will be changed to an unreachable.
Definition MemorySSAUpdater.cpp:1389
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...
Definition MemorySSAUpdater.cpp:529
LLVM_ABI void updatePhisWhenInsertingUniqueBackedgeBlock(BasicBlock *LoopHeader, BasicBlock *LoopPreheader, BasicBlock *BackedgeBlock)
Update MemorySSA when inserting a unique backedge block for a loop.
Definition MemorySSAUpdater.cpp:621
LLVM_ABI void insertUse(MemoryUse *Use, bool RenameUses=false)
Definition MemorySSAUpdater.cpp:238
LLVM_ABI void removeBlocks(const SmallSetVector< BasicBlock *, 8 > &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
Definition MemorySSAUpdater.cpp:1353
LLVM_ABI void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was spliced into From and To.
Definition MemorySSAUpdater.cpp:1228
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.
Definition MemorySSAUpdater.cpp:1410
LLVM_ABI void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
Definition MemorySSAUpdater.cpp:1286
LLVM_ABI void applyInsertUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT)
Apply CFG insert updates, analogous with the DT edge updates.
Definition MemorySSAUpdater.cpp:835
LLVM_ABI MemoryUseOrDef * createMemoryAccessAfter(Instruction *I, MemoryAccess *Definition, MemoryAccess *InsertPt)
Create a MemoryAccess in MemorySSA after an existing MemoryAccess.
Definition MemorySSAUpdater.cpp:1430
LLVM_ABI void updateForClonedBlockIntoPred(BasicBlock *BB, BasicBlock *P1, const ValueToValueMapTy &VM)
Definition MemorySSAUpdater.cpp:729
LLVM_ABI void applyUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT, bool UpdateDTFirst=false)
Apply CFG updates, analogous with the DT edge updates.
Definition MemorySSAUpdater.cpp:784
LLVM_ABI void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was merged into To.
Definition MemorySSAUpdater.cpp:1239
LLVM_ABI void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
Definition MemorySSAUpdater.cpp:1181
LLVM_ABI void wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, BasicBlock *New, ArrayRef< BasicBlock * > Preds, bool IdenticalEdgesWereMerged=true)
A new empty BasicBlock (New) now branches directly to Old.
Definition MemorySSAUpdater.cpp:1249
LLVM_ABI void updateExitBlocksForClonedLoop(ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VMap, DominatorTree &DT)
Update phi nodes in exit block successors following cloning.
Definition MemorySSAUpdater.cpp:762
LLVM_ABI void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where)
Definition MemorySSAUpdater.cpp:1172
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)
iplist< MemoryAccess, ilist_tag< MSSAHelpers::AllAccessTag > > AccessList
AccessList * getWritableBlockAccesses(const BasicBlock *BB) const
InsertionPlace
Used in various insertion functions to specify whether we are talking about the beginning or end of a...
DefsList * getWritableBlockDefs(const BasicBlock *BB) const
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...
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()
LLVM_ABI void 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...
bool hasValueHandle() const
Return true if there is a value handle associated with this value.
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 - 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.
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IDFCalculator< false > ForwardIDFCalculator
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast - 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.