LLVM: lib/CodeGen/MachineSink.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
64#include
65#include
66#include
67#include
68
69using namespace llvm;
70
71#define DEBUG_TYPE "machine-sink"
72
75 cl::desc("Split critical edges during machine sinking"),
77
79 "machine-sink-bfi",
80 cl::desc("Use block frequency info to find successors to sink"),
82
84 "machine-sink-split-probability-threshold",
86 "Percentage threshold for splitting single-instruction critical edge. "
87 "If the branch threshold is higher than this threshold, we allow "
88 "speculative execution of up to 1 instruction to avoid branching to "
89 "splitted critical edge"),
91
93 "machine-sink-load-instrs-threshold",
94 cl::desc("Do not try to find alias store for a load if there is a in-path "
95 "block whose instruction number is higher than this threshold."),
97
99 "machine-sink-load-blocks-threshold",
100 cl::desc("Do not try to find alias store for a load if the block number in "
101 "the straight line is higher than this threshold."),
103
106 cl::desc("Sink instructions into cycles to avoid "
107 "register spills"),
109
111 "machine-sink-cycle-limit",
113 "The maximum number of instructions considered for cycle sinking."),
115
116STATISTIC(NumSunk, "Number of machine instructions sunk");
117STATISTIC(NumCycleSunk, "Number of machine instructions sunk into a cycle");
118STATISTIC(NumSplit, "Number of critical edges split");
119STATISTIC(NumCoalesces, "Number of copies coalesced");
120STATISTIC(NumPostRACopySink, "Number of copies sunk after RA");
121
123
124namespace {
125
126class MachineSinking {
140
145
146
148 CEBCandidates;
149
150
151
152
153
154
156 CEMergeCandidates;
157
158
159
161
163
164 using AllSuccsCache =
166
167
168
169
170
171
172
173
174
175
177
178 using SinkItem = std::pair<MachineInstr *, MachineBasicBlock *>;
179
180
181
183
184
185
187
189 HasStoreCache;
190
193 StoreInstrCache;
194
195
197 CachedRegisterPressure;
198
199 bool EnableSinkAndFold;
200
201public:
208 : DT(DT), PDT(PDT), CI(CI), PSI(PSI), MBFI(MBFI), MBPI(MBPI), AA(AA),
209 LIS(LIS), SI(SI), LV(LV), MLI(MLI),
210 EnableSinkAndFold(EnableSinkAndFold) {}
211
213
214 void releaseMemory() {
215 CEBCandidates.clear();
216 CEMergeCandidates.clear();
217 }
218
219private:
227
230
231
232
233
234
235
236
237
238
239
240
241
242
246 AllSuccsCache &AllSuccessors);
247
248
249
250
251
252 void SalvageUnsunkDebugUsersOfCopy(MachineInstr &,
256 bool &LocalUse) const;
258 bool &BreakPHIEdge,
259 AllSuccsCache &AllSuccessors);
260
263
264 bool
267
271 AllSuccsCache &AllSuccessors);
272
273 bool PerformTrivialForwardCoalescing(MachineInstr &MI,
275
277
280 AllSuccsCache &AllSuccessors) const;
281
283 bool UseCache = true);
284
285 bool registerPressureSetExceedsLimit(unsigned NRegs,
288
290};
291
293public:
294 static char ID;
295
298 }
299
301
302 void getAnalysisUsage(AnalysisUsage &AU) const override {
315 }
316};
317
318}
319
320char MachineSinkingLegacy::ID = 0;
321
323
325 false, false)
333
334
335
343 ++PI) {
344
345 if (!TII->isBasicBlockPrologue(*PI))
346 continue;
347 for (auto &MO : MI.operands()) {
348 if (!MO.isReg())
349 continue;
350 Register Reg = MO.getReg();
351 if (!Reg)
352 continue;
353 if (MO.isUse()) {
354 if (Reg.isPhysical() &&
355 (TII->isIgnorableUse(MO) || (MRI && MRI->isConstantPhysReg(Reg))))
356 continue;
357 if (PI->modifiesRegister(Reg, TRI))
358 return true;
359 } else {
360 if (PI->readsRegister(Reg, TRI))
361 return true;
362
363 auto *DefOp = PI->findRegisterDefOperand(Reg, TRI, false, true);
364 if (DefOp && !DefOp->isDead())
365 return true;
366 }
367 }
368 }
369
370 return false;
371}
372
373bool MachineSinking::PerformTrivialForwardCoalescing(MachineInstr &MI,
375 if (.isCopy())
376 return false;
377
378 Register SrcReg = MI.getOperand(1).getReg();
379 Register DstReg = MI.getOperand(0).getReg();
381 ->hasOneNonDBGUse(SrcReg))
382 return false;
383
384 const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
385 const TargetRegisterClass *DRC = MRI->getRegClass(DstReg);
386 if (SRC != DRC)
387 return false;
388
389 MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
391 return false;
394 MRI->replaceRegWith(DstReg, SrcReg);
395 MI.eraseFromParent();
396
397
398
399 MRI->clearKillFlags(SrcReg);
400
401 ++NumCoalesces;
402 return true;
403}
404
405bool MachineSinking::PerformSinkAndFold(MachineInstr &MI,
406 MachineBasicBlock *MBB) {
407 if (MI.isCopy() || MI.mayLoadOrStore() ||
408 MI.getOpcode() == TargetOpcode::REG_SEQUENCE)
409 return false;
410
411
413 return false;
414
415
416 bool SawStore = true;
417 if (.isSafeToMove(SawStore))
418 return false;
419
420
421
422 if (MI.isConvergent())
423 return false;
424
425
426
427
428
431 for (const MachineOperand &MO : MI.operands()) {
432 if (MO.isImm() || MO.isRegMask() || MO.isRegLiveOut() || MO.isMetadata() ||
433 MO.isMCSymbol() || MO.isDbgInstrRef() || MO.isCFIIndex() ||
434 MO.isIntrinsicID() || MO.isPredicate() || MO.isShuffleMask())
435 continue;
436 if (!MO.isReg())
437 return false;
438
440 if (Reg == 0)
441 continue;
442
444 if (MO.isDef()) {
445 if (DefReg)
446 return false;
447 DefReg = Reg;
448 continue;
449 }
450
451 if (UsedRegA == 0)
452 UsedRegA = Reg;
453 else if (UsedRegB == 0)
454 UsedRegB = Reg;
455 else
456 return false;
457 continue;
458 }
459
462 continue;
463
464 return false;
465 }
466
467
468
469
470
471 using SinkInfo = std::pair<MachineInstr *, ExtAddrMode>;
474
475 const TargetRegisterClass *RC = MRI->getRegClass(DefReg);
476 const TargetRegisterClass *RCA =
477 UsedRegA == 0 ? nullptr : MRI->getRegClass(UsedRegA);
478 const TargetRegisterClass *RCB =
479 UsedRegB == 0 ? nullptr : MRI->getRegClass(UsedRegB);
480
482 while (!Worklist.empty()) {
484
485 for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
486 ExtAddrMode MaybeAM;
487 MachineInstr &UseInst = *MO.getParent();
488 if (UseInst.isCopy()) {
490 if (const MachineOperand &O = UseInst.getOperand(0); O.isReg())
491 DstReg = O.getReg();
492 if (DstReg == 0)
493 return false;
496 continue;
497 }
498
499
501 return false;
502
503
505 return false;
507 ExtAddrMode AM;
509 return false;
510 MaybeAM = AM;
511 } else {
512 return false;
513 }
514
515 if (UseInst.getParent() != MI.getParent()) {
516
517
518
519 const TargetRegisterClass *RCS = MRI->getRegClass(Reg);
521 RCA = nullptr;
523 RCB = nullptr;
524 if (RCA || RCB) {
525 if (RCA == nullptr) {
526 RCA = RCB;
527 RCB = nullptr;
528 }
529
530 unsigned NRegs = !!RCA + !!RCB;
531 if (RCA == RCB)
532 RCB = nullptr;
533
534
535 const MachineBasicBlock &MBB = *UseInst.getParent();
536 if (RCB == nullptr) {
537 if (registerPressureSetExceedsLimit(NRegs, RCA, MBB))
538 return false;
539 } else if (registerPressureSetExceedsLimit(1, RCA, MBB) ||
540 registerPressureSetExceedsLimit(1, RCB, MBB)) {
541 return false;
542 }
543 }
544 }
545
547 }
548 }
549
550 if (SinkInto.empty())
551 return false;
552
553
554 for (auto &[SinkDst, MaybeAM] : SinkInto) {
555 MachineInstr *New = nullptr;
557 SinkDst->dump());
558 if (SinkDst->isCopy()) {
559
560
561
562
563
564
565
566
567
568
569
571 Register DstReg = SinkDst->getOperand(0).getReg();
573 New = &*std::prev(InsertPt);
574 if (->getDebugLoc())
575 New->setDebugLoc(SinkDst->getDebugLoc());
576
577
578
579
580 if (UsedRegA)
581 MRI->clearKillFlags(UsedRegA);
582 if (UsedRegB)
583 MRI->clearKillFlags(UsedRegB);
584 } else {
585
587
588
589
590
592 MRI->clearKillFlags(R);
594 MRI->clearKillFlags(R);
595 }
597
598 if (SinkDst->mayStore() && !SinkDst->hasOrderedMemoryRef())
599 StoreInstrCache.clear();
600 SinkDst->eraseFromParent();
601 }
602
603
604
605
608 while (!Worklist.empty()) {
610 for (MachineOperand &MO : MRI->use_operands(Reg)) {
611 MachineInstr *U = MO.getParent();
612 assert((U->isCopy() || U->isDebugInstr()) &&
613 "Only debug uses and copies must remain");
614 if (U->isCopy())
615 Worklist.push_back(U->getOperand(0).getReg());
617 }
618 }
619
620
621 for (MachineOperand *MO : Cleanup) {
622 MachineInstr *I = MO->getParent();
623 if (I->isCopy()) {
624 I->eraseFromParent();
625 } else {
626 MO->setReg(0);
627 MO->setSubReg(0);
628 }
629 }
630
631 MI.eraseFromParent();
632 return true;
633}
634
635
636
637
638
639bool MachineSinking::AllUsesDominatedByBlock(Register Reg,
640 MachineBasicBlock *MBB,
641 MachineBasicBlock *DefMBB,
642 bool &BreakPHIEdge,
643 bool &LocalUse) const {
645
646
647 if (MRI->use_nodbg_empty(Reg))
648 return true;
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664 if (all_of(MRI->use_nodbg_operands(Reg), [&](MachineOperand &MO) {
665 MachineInstr *UseInst = MO.getParent();
666 unsigned OpNo = MO.getOperandNo();
667 MachineBasicBlock *UseBlock = UseInst->getParent();
668 return UseBlock == MBB && UseInst->isPHI() &&
669 UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
670 })) {
671 BreakPHIEdge = true;
672 return true;
673 }
674
675 for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
676
677 MachineInstr *UseInst = MO.getParent();
678 unsigned OpNo = &MO - &UseInst->getOperand(0);
679 MachineBasicBlock *UseBlock = UseInst->getParent();
680 if (UseInst->isPHI()) {
681
682
684 } else if (UseBlock == DefMBB) {
685 LocalUse = true;
686 return false;
687 }
688
689
691 return false;
692 }
693
694 return true;
695}
696
697
698
700 assert(MI.mayLoad() && "Expected MI that loads!");
701
702
703
704 if (MI.memoperands_empty())
705 return true;
706
709 if (PSV->isGOT() || PSV->isConstantPool())
710 return true;
711
712 return false;
713}
714
715void MachineSinking::FindCycleSinkCandidates(
717 SmallVectorImpl<MachineInstr *> &Candidates) {
718 for (auto &MI : *BB) {
719 LLVM_DEBUG(dbgs() << "CycleSink: Analysing candidate: " << MI);
720 if (MI.isMetaInstruction()) {
721 LLVM_DEBUG(dbgs() << "CycleSink: not sinking meta instruction\n");
722 continue;
723 }
725 LLVM_DEBUG(dbgs() << "CycleSink: Instruction not a candidate for this "
726 "target\n");
727 continue;
728 }
730 LLVM_DEBUG(dbgs() << "CycleSink: Instruction is not cycle invariant\n");
731 continue;
732 }
733 bool DontMoveAcrossStore = true;
734 if (.isSafeToMove(DontMoveAcrossStore)) {
735 LLVM_DEBUG(dbgs() << "CycleSink: Instruction not safe to move.\n");
736 continue;
737 }
739 LLVM_DEBUG(dbgs() << "CycleSink: Dont sink GOT or constant pool loads\n");
740 continue;
741 }
742 if (MI.isConvergent())
743 continue;
744
745 const MachineOperand &MO = MI.getOperand(0);
747 continue;
748 if (->hasOneDef(MO.getReg()))
749 continue;
750
751 LLVM_DEBUG(dbgs() << "CycleSink: Instruction added as candidate.\n");
753 }
754}
755
756PreservedAnalyses
763 .getCachedResult(
767 : nullptr;
770 .getManager()
776 MachineSinking Impl(EnableSinkAndFold, DT, PDT, LV, MLI, SI, LIS, CI, PSI,
777 MBFI, MBPI, AA);
778 bool Changed = Impl.run(MF);
784 return PA;
785}
786
789 OS << MapClassName2PassName(name());
790 if (EnableSinkAndFold)
791 OS << "";
792}
793
794bool MachineSinkingLegacy::runOnMachineFunction(MachineFunction &MF) {
796 return false;
797
798 TargetPassConfig *PassConfig = &getAnalysis();
800
801 auto *DT = &getAnalysis().getDomTree();
802 auto *PDT =
803 &getAnalysis().getPostDomTree();
804 auto *CI = &getAnalysis().getCycleInfo();
805 auto *PSI = &getAnalysis().getPSI();
806 auto *MBFI =
808 ? &getAnalysis().getMBFI()
809 : nullptr;
810 auto *MBPI =
811 &getAnalysis().getMBPI();
812 auto *AA = &getAnalysis().getAAResults();
813
814 auto *LISWrapper = getAnalysisIfAvailable();
815 auto *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
816 auto *SIWrapper = getAnalysisIfAvailable();
817 auto *SI = SIWrapper ? &SIWrapper->getSI() : nullptr;
818 auto *LVWrapper = getAnalysisIfAvailable();
819 auto *LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
820 auto *MLIWrapper = getAnalysisIfAvailable();
821 auto *MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;
822
823 MachineSinking Impl(EnableSinkAndFold, DT, PDT, LV, MLI, SI, LIS, CI, PSI,
824 MBFI, MBPI, AA);
825 return Impl.run(MF);
826}
827
829 LLVM_DEBUG(dbgs() << "******** Machine Sinking ********\n");
830
835
837
838 bool EverMadeChange = false;
839
840 while (true) {
841 bool MadeChange = false;
842
843
844 CEBCandidates.clear();
845 CEMergeCandidates.clear();
846 ToSplit.clear();
847 for (auto &MBB : MF)
849
850
852 MachineDomTreeUpdater::UpdateStrategy::Lazy);
853 for (const auto &Pair : ToSplit) {
854 auto NewSucc = Pair.first->SplitCriticalEdge(
855 Pair.second, {LIS, SI, LV, MLI}, nullptr, &MDTU);
856 if (NewSucc != nullptr) {
857 LLVM_DEBUG(dbgs() << " *** Splitting critical edge: "
861 if (MBFI)
862 MBFI->onEdgeSplit(*Pair.first, *NewSucc, *MBPI);
863
864 MadeChange = true;
865 ++NumSplit;
867 } else
868 LLVM_DEBUG(dbgs() << " *** Not legal to break critical edge\n");
869 }
870
871 if (!MadeChange)
872 break;
873 EverMadeChange = true;
874 }
875
878 SchedModel.init(STI);
879 bool HasHighPressure;
880
881 DenseMap<SinkItem, MachineInstr *> SunkInstrs;
882
883 enum CycleSinkStage { COPY, LOW_LATENCY, AGGRESSIVE, END };
884 for (unsigned Stage = CycleSinkStage::COPY; Stage != CycleSinkStage::END;
885 ++Stage, SunkInstrs.clear()) {
886 HasHighPressure = false;
887
888 for (auto *Cycle : Cycles) {
890 if (!Preheader) {
891 LLVM_DEBUG(dbgs() << "CycleSink: Can't find preheader\n");
892 continue;
893 }
894 SmallVector<MachineInstr *, 8> Candidates;
895 FindCycleSinkCandidates(Cycle, Preheader, Candidates);
896
897 unsigned i = 0;
898
899
900
901
903
904 if (Stage == CycleSinkStage::COPY) {
907 << "CycleSink: Limit reached of instructions to "
908 "be analyzed.");
909 break;
910 }
911
912 if (->isCopy())
913 continue;
914 }
915
916
917
918 if (Stage == CycleSinkStage::LOW_LATENCY &&
920 continue;
921
922 if (!aggressivelySinkIntoCycle(Cycle, *I, SunkInstrs))
923 continue;
924 EverMadeChange = true;
925 ++NumCycleSunk;
926 }
927
928
929 if (!HasHighPressure)
930 HasHighPressure = registerPressureExceedsLimit(*Preheader);
931 }
932 if (!HasHighPressure)
933 break;
934 }
935 }
936
937 HasStoreCache.clear();
938 StoreInstrCache.clear();
939
940
941 for (auto I : RegsToClearKillFlags)
943 RegsToClearKillFlags.clear();
944
945 releaseMemory();
946 return EverMadeChange;
947}
948
949bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
951 return false;
952
953
954
955
957 return false;
958
959 bool MadeChange = false;
960
961
962 AllSuccsCache AllSuccessors;
963
964
966 --I;
967 bool ProcessedBegin, SawStore = false;
968 do {
970
971
972
973 ProcessedBegin = I == MBB.begin();
974 if (!ProcessedBegin)
975 --I;
976
977 if (MI.isDebugOrPseudoInstr() || MI.isFakeUse()) {
978 if (MI.isDebugValue())
979 ProcessDbgInst(MI);
980 continue;
981 }
982
983 if (EnableSinkAndFold && PerformSinkAndFold(MI, &MBB)) {
984 MadeChange = true;
985 continue;
986 }
987
988
990 continue;
991
992 if (PerformTrivialForwardCoalescing(MI, &MBB)) {
993 MadeChange = true;
994 continue;
995 }
996
998 ++NumSunk;
999 MadeChange = true;
1000 }
1001
1002
1003 } while (!ProcessedBegin);
1004
1005 SeenDbgUsers.clear();
1006 SeenDbgVars.clear();
1007
1008 CachedRegisterPressure.clear();
1009 return MadeChange;
1010}
1011
1012void MachineSinking::ProcessDbgInst(MachineInstr &MI) {
1013
1014
1015 assert(MI.isDebugValue() && "Expected DBG_VALUE for processing");
1016
1017 DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
1018 MI.getDebugLoc()->getInlinedAt());
1019 bool SeenBefore = SeenDbgVars.contains(Var);
1020
1021 for (MachineOperand &MO : MI.debug_operands()) {
1023 SeenDbgUsers[MO.getReg()].push_back(SeenDbgUser(&MI, SeenBefore));
1024 }
1025
1026
1027 SeenDbgVars.insert(Var);
1028}
1029
1030bool MachineSinking::isWorthBreakingCriticalEdge(
1031 MachineInstr &MI, MachineBasicBlock *From, MachineBasicBlock *To,
1032 MachineBasicBlock *&DeferredFromBlock) {
1033
1034
1035
1036
1037
1038 if (!CEBCandidates.insert(std::make_pair(From, To)).second)
1039 return true;
1040
1042 return true;
1043
1044
1045
1046
1047
1048
1049 for (const auto &MO : MI.all_defs()) {
1051 if ()
1052 continue;
1054 auto Key = std::make_pair(SrcReg, To);
1055 auto Res = CEMergeCandidates.try_emplace(Key, From);
1056
1057
1058 if (!Res.second) {
1059
1060 DeferredFromBlock = Res.first->second;
1061 return true;
1062 }
1063 }
1064
1068 return true;
1069
1070
1071
1072
1073 for (const MachineOperand &MO : MI.all_uses()) {
1075 if (Reg == 0)
1076 continue;
1077
1078
1079
1081 continue;
1082
1083
1084
1085
1086 if (MRI->hasOneNonDBGUse(Reg)) {
1087
1088
1089
1090
1091 MachineInstr *DefMI = MRI->getVRegDef(Reg);
1093 return true;
1094 }
1095 }
1096
1097
1098
1100}
1101
1102bool MachineSinking::isLegalToBreakCriticalEdge(MachineInstr &MI,
1103 MachineBasicBlock *FromBB,
1104 MachineBasicBlock *ToBB,
1105 bool BreakPHIEdge) {
1106
1108 return false;
1109
1112
1113
1114 if (FromCycle == ToCycle && FromCycle &&
1116 return false;
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157 if (!BreakPHIEdge) {
1158 for (MachineBasicBlock *Pred : ToBB->predecessors())
1159 if (Pred != FromBB && !DT->dominates(ToBB, Pred))
1160 return false;
1161 }
1162
1163 return true;
1164}
1165
1166bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI,
1167 MachineBasicBlock *FromBB,
1168 MachineBasicBlock *ToBB,
1169 bool BreakPHIEdge) {
1170 bool Status = false;
1171 MachineBasicBlock *DeferredFromBB = nullptr;
1172 if (isWorthBreakingCriticalEdge(MI, FromBB, ToBB, DeferredFromBB)) {
1173
1174
1175 if ((!DeferredFromBB ||
1176 ToSplit.count(std::make_pair(DeferredFromBB, ToBB)) ||
1177 isLegalToBreakCriticalEdge(MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&
1178 isLegalToBreakCriticalEdge(MI, FromBB, ToBB, BreakPHIEdge)) {
1179 ToSplit.insert(std::make_pair(FromBB, ToBB));
1180 if (DeferredFromBB)
1181 ToSplit.insert(std::make_pair(DeferredFromBB, ToBB));
1182 Status = true;
1183 }
1184 }
1185
1186 return Status;
1187}
1188
1189std::vector &
1190MachineSinking::getBBRegisterPressure(const MachineBasicBlock &MBB,
1191 bool UseCache) {
1192
1193
1194
1195
1196
1197 auto RP = CachedRegisterPressure.find(&MBB);
1198 if (UseCache && RP != CachedRegisterPressure.end())
1199 return RP->second;
1200
1201 RegionPressure Pressure;
1202 RegPressureTracker RPTracker(Pressure);
1203
1204
1206 false, true);
1207
1210 MII != MIE; --MII) {
1211 const MachineInstr &MI = *std::prev(MII);
1212 if (MI.isDebugOrPseudoInstr())
1213 continue;
1214 RegisterOperands RegOpers;
1216 RPTracker.recedeSkipDebugValues();
1217 assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
1218 RPTracker.recede(RegOpers);
1219 }
1220
1221 RPTracker.closeRegion();
1222
1223 if (RP != CachedRegisterPressure.end()) {
1224 CachedRegisterPressure[&MBB] = RPTracker.getPressure().MaxSetPressure;
1225 return CachedRegisterPressure[&MBB];
1226 }
1227
1228 auto It = CachedRegisterPressure.insert(
1229 std::make_pair(&MBB, RPTracker.getPressure().MaxSetPressure));
1230 return It.first->second;
1231}
1232
1233bool MachineSinking::registerPressureSetExceedsLimit(
1234 unsigned NRegs, const TargetRegisterClass *RC,
1235 const MachineBasicBlock &MBB) {
1236 unsigned Weight = NRegs * TRI->getRegClassWeight(RC).RegWeight;
1237 const int *PS = TRI->getRegClassPressureSets(RC);
1238 std::vector BBRegisterPressure = getBBRegisterPressure(MBB);
1239 for (; *PS != -1; PS++)
1240 if (Weight + BBRegisterPressure[*PS] >=
1242 return true;
1243 return false;
1244}
1245
1246
1247bool MachineSinking::registerPressureExceedsLimit(
1248 const MachineBasicBlock &MBB) {
1249 std::vector BBRegisterPressure = getBBRegisterPressure(MBB, false);
1250
1251 for (unsigned PS = 0; PS < BBRegisterPressure.size(); ++PS) {
1252 if (BBRegisterPressure[PS] >=
1254 return true;
1255 }
1256 }
1257
1258 return false;
1259}
1260
1261
1262bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
1263 MachineBasicBlock *MBB,
1264 MachineBasicBlock *SuccToSinkTo,
1265 AllSuccsCache &AllSuccessors) {
1266 assert(SuccToSinkTo && "Invalid SinkTo Candidate BB");
1267
1268 if (MBB == SuccToSinkTo)
1269 return false;
1270
1271
1273 return true;
1274
1275
1276
1278 return true;
1279
1280
1281 bool NonPHIUse = false;
1282 for (MachineInstr &UseInst : MRI->use_nodbg_instructions(Reg)) {
1283 MachineBasicBlock *UseBlock = UseInst.getParent();
1284 if (UseBlock == SuccToSinkTo && !UseInst.isPHI())
1285 NonPHIUse = true;
1286 }
1287 if (!NonPHIUse)
1288 return true;
1289
1290
1291
1292 bool BreakPHIEdge = false;
1293
1294 if (MachineBasicBlock *MBB2 =
1295 FindSuccToSinkTo(MI, SuccToSinkTo, BreakPHIEdge, AllSuccessors))
1296 return isProfitableToSinkTo(Reg, MI, SuccToSinkTo, MBB2, AllSuccessors);
1297
1299
1300
1301
1302 if (!MCycle)
1303 return false;
1304
1305
1306
1307 for (const MachineOperand &MO : MI.operands()) {
1308
1309 if (!MO.isReg())
1310 continue;
1312 if (Reg == 0)
1313 continue;
1314
1316
1317 if (MO.isUse() && ->isConstantPhysReg(Reg) &&
1319 return false;
1320 continue;
1321 }
1322
1323
1324 if (MO.isDef()) {
1325
1326 bool LocalUse = false;
1327 if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB, BreakPHIEdge,
1328 LocalUse))
1329 return false;
1330 } else {
1331 MachineInstr *DefMI = MRI->getVRegDef(Reg);
1333 continue;
1335
1336
1337
1338
1341 continue;
1342
1343
1344
1345 if (registerPressureSetExceedsLimit(1, MRI->getRegClass(Reg),
1346 *SuccToSinkTo)) {
1347 LLVM_DEBUG(dbgs() << "register pressure exceed limit, not profitable.");
1348 return false;
1349 }
1350 }
1351 }
1352
1353
1354
1355
1356 return true;
1357}
1358
1359
1360
1361SmallVector<MachineBasicBlock *, 4> &
1362MachineSinking::GetAllSortedSuccessors(MachineInstr &MI, MachineBasicBlock *MBB,
1363 AllSuccsCache &AllSuccessors) const {
1364
1365 auto Succs = AllSuccessors.find(MBB);
1366 if (Succs != AllSuccessors.end())
1367 return Succs->second;
1368
1369 SmallVector<MachineBasicBlock *, 4> AllSuccs(MBB->successors());
1370
1371
1372
1373
1374
1375
1376
1377
1379
1380 if (DTChild->getIDom()->getBlock() == MI.getParent() &&
1381
1383 AllSuccs.push_back(DTChild->getBlock());
1384 }
1385
1386
1388 AllSuccs, [&](const MachineBasicBlock *L, const MachineBasicBlock *R) {
1392 (!LHSFreq && !RHSFreq))
1394 return LHSFreq < RHSFreq;
1395 });
1396
1397 auto it = AllSuccessors.insert(std::make_pair(MBB, AllSuccs));
1398
1399 return it.first->second;
1400}
1401
1402
1403MachineBasicBlock *
1404MachineSinking::FindSuccToSinkTo(MachineInstr &MI, MachineBasicBlock *MBB,
1405 bool &BreakPHIEdge,
1406 AllSuccsCache &AllSuccessors) {
1407 assert(MBB && "Invalid MachineBasicBlock!");
1408
1409
1410
1411
1412
1413
1414 MachineBasicBlock *SuccToSinkTo = nullptr;
1415 for (const MachineOperand &MO : MI.operands()) {
1416 if (!MO.isReg())
1417 continue;
1418
1420 if (Reg == 0)
1421 continue;
1422
1424 if (MO.isUse()) {
1425
1426
1427
1429 return nullptr;
1430 } else if (!MO.isDead()) {
1431
1432 return nullptr;
1433 }
1434 } else {
1435
1437 continue;
1438
1439
1441 return nullptr;
1442
1443
1444
1445 if (SuccToSinkTo) {
1446
1447
1448 bool LocalUse = false;
1449 if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, MBB, BreakPHIEdge,
1450 LocalUse))
1451 return nullptr;
1452
1453 continue;
1454 }
1455
1456
1457
1458
1459
1460 for (MachineBasicBlock *SuccBlock :
1461 GetAllSortedSuccessors(MI, MBB, AllSuccessors)) {
1462 bool LocalUse = false;
1463 if (AllUsesDominatedByBlock(Reg, SuccBlock, MBB, BreakPHIEdge,
1464 LocalUse)) {
1465 SuccToSinkTo = SuccBlock;
1466 break;
1467 }
1468 if (LocalUse)
1469
1470 return nullptr;
1471 }
1472
1473
1474 if (!SuccToSinkTo)
1475 return nullptr;
1476 if (!isProfitableToSinkTo(Reg, MI, MBB, SuccToSinkTo, AllSuccessors))
1477 return nullptr;
1478 }
1479 }
1480
1481
1482
1483 if (MBB == SuccToSinkTo)
1484 return nullptr;
1485
1486
1487
1488 if (SuccToSinkTo && SuccToSinkTo->isEHPad())
1489 return nullptr;
1490
1491
1492
1493
1494
1496 return nullptr;
1497
1499 return nullptr;
1500
1501 return SuccToSinkTo;
1502}
1503
1504
1505
1506
1507
1508
1509
1510
1515
1516 auto *MBB = MI.getParent();
1517 if (MBB->pred_size() != 1)
1518 return false;
1519
1520 auto *PredMBB = *MBB->pred_begin();
1521 auto *PredBB = PredMBB->getBasicBlock();
1522
1523
1524
1525
1526 if (!PredBB ||
1527 !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))
1528 return false;
1529
1532 bool OffsetIsScalable;
1533 if (->getMemOperandWithOffset(MI, BaseOp, Offset, OffsetIsScalable, TRI))
1534 return false;
1535
1536 if (!BaseOp->isReg())
1537 return false;
1538
1539 if (!(MI.mayLoad() && .isPredicable()))
1540 return false;
1541
1542 MachineBranchPredicate MBP;
1543 if (TII->analyzeBranchPredicate(*PredMBB, MBP, false))
1544 return false;
1545
1546 return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
1547 (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
1548 MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&
1549 MBP.LHS.getReg() == BaseOp->getReg();
1550}
1551
1552
1553
1554
1555
1560
1561
1562
1563
1564
1565 const MachineOperand *SrcMO = nullptr, *DstMO = nullptr;
1566 auto CopyOperands = TII.isCopyInstr(SinkInst);
1567 if (!CopyOperands)
1568 return false;
1569 SrcMO = CopyOperands->Source;
1570 DstMO = CopyOperands->Destination;
1571
1572
1573 bool PostRA = MRI.getNumVirtRegs() == 0;
1574
1575
1577 return false;
1578
1579
1580
1581 bool arePhysRegs = .isVirtual();
1582 if (arePhysRegs != PostRA)
1583 return false;
1584
1585
1586
1587 if (!PostRA)
1589 if (DbgMO.getSubReg() != SrcMO->getSubReg() ||
1590 DbgMO.getSubReg() != DstMO->getSubReg())
1591 return false;
1592
1593
1594
1595
1596 if (PostRA && Reg != DstMO->getReg())
1597 return false;
1598
1600 DbgMO.setReg(SrcMO->getReg());
1601 DbgMO.setSubReg(SrcMO->getSubReg());
1602 }
1603 return true;
1604}
1605
1606using MIRegs = std::pair<MachineInstr *, SmallVector<Register, 2>>;
1607
1611
1612
1613
1614 if (!SuccToSinkTo.empty() && InsertPos != SuccToSinkTo.end())
1616 InsertPos->getDebugLoc()));
1617 else
1619
1620
1622 SuccToSinkTo.splice(InsertPos, ParentBlock, MI,
1624
1625
1626
1627
1628
1629 for (const auto &DbgValueToSink : DbgValuesToSink) {
1631 MachineInstr *NewDbgMI = DbgMI->getMF()->CloneMachineInstr(DbgMI);
1632 SuccToSinkTo.insert(InsertPos, NewDbgMI);
1633
1634 bool PropagatedAllSunkOps = true;
1635 for (Register Reg : DbgValueToSink.second) {
1638 PropagatedAllSunkOps = false;
1639 break;
1640 }
1641 }
1642 }
1643 if (!PropagatedAllSunkOps)
1645 }
1646}
1647
1648
1649
1650bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
1651 MachineBasicBlock *To, MachineInstr &MI) {
1652
1653
1655 return true;
1656
1657 auto BlockPair = std::make_pair(From, To);
1658
1659
1660
1661 if (auto It = HasStoreCache.find(BlockPair); It != HasStoreCache.end())
1662 return It->second;
1663
1664 if (auto It = StoreInstrCache.find(BlockPair); It != StoreInstrCache.end())
1665 return llvm::any_of(It->second, [&](MachineInstr *I) {
1666 return I->mayAlias(AA, MI, false);
1667 });
1668
1669 bool SawStore = false;
1670 bool HasAliasedStore = false;
1671 DenseSet<MachineBasicBlock *> HandledBlocks;
1672 DenseSet<MachineBasicBlock *> HandledDomBlocks;
1673
1674 for (MachineBasicBlock *BB : depth_first(From)) {
1675
1676
1677
1678
1679 if (BB == To || BB == From)
1680 continue;
1681
1682
1683 if (HandledBlocks.count(BB))
1684 continue;
1685
1686 HandledBlocks.insert(BB);
1687
1689 if (!HandledDomBlocks.count(BB))
1690 HandledDomBlocks.insert(BB);
1691
1692
1693
1696 for (auto *DomBB : HandledDomBlocks) {
1697 if (DomBB != BB && DT->dominates(DomBB, BB))
1698 HasStoreCache[std::make_pair(DomBB, To)] = true;
1699 else if (DomBB != BB && DT->dominates(BB, DomBB))
1700 HasStoreCache[std::make_pair(From, DomBB)] = true;
1701 }
1702 HasStoreCache[BlockPair] = true;
1703 return true;
1704 }
1705
1706 for (MachineInstr &I : *BB) {
1707
1708
1709 if (I.isCall() || I.hasOrderedMemoryRef()) {
1710 for (auto *DomBB : HandledDomBlocks) {
1711 if (DomBB != BB && DT->dominates(DomBB, BB))
1712 HasStoreCache[std::make_pair(DomBB, To)] = true;
1713 else if (DomBB != BB && DT->dominates(BB, DomBB))
1714 HasStoreCache[std::make_pair(From, DomBB)] = true;
1715 }
1716 HasStoreCache[BlockPair] = true;
1717 return true;
1718 }
1719
1720 if (I.mayStore()) {
1721 SawStore = true;
1722
1723
1724
1725
1726 if (I.mayAlias(AA, MI, false))
1727 HasAliasedStore = true;
1728 StoreInstrCache[BlockPair].push_back(&I);
1729 }
1730 }
1731 }
1732 }
1733
1734 if (!SawStore)
1735 HasStoreCache[BlockPair] = false;
1736 return HasAliasedStore;
1737}
1738
1739
1740
1741
1742
1743
1744bool MachineSinking::aggressivelySinkIntoCycle(
1746 DenseMap<SinkItem, MachineInstr *> &SunkInstrs) {
1747
1748 if (I.getNumDefs() > 1)
1749 return false;
1750
1751 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Finding sink block for: " << I);
1754
1755 MachineOperand &DefMO = I.getOperand(0);
1756 for (MachineInstr &MI : MRI->use_instructions(DefMO.getReg())) {
1758 }
1759
1760 for (std::pair<RegSubRegPair, MachineInstr *> Entry : Uses) {
1761 MachineInstr *MI = Entry.second;
1762 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Analysing use: " << MI);
1763 if (MI->isPHI()) {
1765 dbgs() << "AggressiveCycleSink: Not attempting to sink for PHI.\n");
1766 continue;
1767 }
1768
1770 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Use is BasicBlock prologue, "
1771 "can't sink.\n");
1772 continue;
1773 }
1776 dbgs() << "AggressiveCycleSink: Use not in cycle, can't sink.\n");
1777 continue;
1778 }
1779
1780 MachineBasicBlock *SinkBlock = MI->getParent();
1781 MachineInstr *NewMI = nullptr;
1782 SinkItem MapEntry(&I, SinkBlock);
1783
1784 auto SI = SunkInstrs.find(MapEntry);
1785
1786
1787
1788 if (SI != SunkInstrs.end()) {
1789 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Already sunk to block: "
1791 NewMI = SI->second;
1792 }
1793
1794
1795 if (!NewMI) {
1796 LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Sinking instruction to block: "
1798
1799 NewMI = I.getMF()->CloneMachineInstr(&I);
1801 const TargetRegisterClass *TRC = MRI->getRegClass(DefMO.getReg());
1802 Register DestReg = MRI->createVirtualRegister(TRC);
1805 }
1807 NewMI);
1808 SunkInstrs.insert({MapEntry, NewMI});
1809 }
1810
1811
1812 for (MachineOperand &MO : NewMI->all_uses()) {
1814 RegsToClearKillFlags.insert(MO.getReg());
1815 }
1816
1817
1818
1821
1822
1826 }
1827
1829 I.eraseFromParent();
1830 return true;
1831}
1832
1833
1834
1835bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
1836 AllSuccsCache &AllSuccessors) {
1837
1839 return false;
1840
1841
1842 if (.isSafeToMove(SawStore))
1843 return false;
1844
1845
1846
1847 if (MI.isConvergent())
1848 return false;
1849
1850
1851
1853 return false;
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863 bool BreakPHIEdge = false;
1864 MachineBasicBlock *ParentBlock = MI.getParent();
1865 MachineBasicBlock *SuccToSinkTo =
1866 FindSuccToSinkTo(MI, ParentBlock, BreakPHIEdge, AllSuccessors);
1867
1868
1869 if (!SuccToSinkTo)
1870 return false;
1871
1872
1873
1874
1875 for (const MachineOperand &MO : MI.all_defs()) {
1878 continue;
1880 return false;
1881 }
1882
1883 LLVM_DEBUG(dbgs() << "Sink instr " << MI << "\tinto block " << *SuccToSinkTo);
1884
1885
1886
1887 if (SuccToSinkTo->pred_size() > 1) {
1888
1889
1890 bool TryBreak = false;
1892 MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo, MI) : true;
1893 if (.isSafeToMove(Store)) {
1894 LLVM_DEBUG(dbgs() << " *** NOTE: Won't sink load along critical edge.\n");
1895 TryBreak = true;
1896 }
1897
1898
1899
1900 if (!TryBreak && !DT->dominates(ParentBlock, SuccToSinkTo)) {
1901 LLVM_DEBUG(dbgs() << " *** NOTE: Critical edge found\n");
1902 TryBreak = true;
1903 }
1904
1905
1906 if (!TryBreak && CI->getCycle(SuccToSinkTo) &&
1909 LLVM_DEBUG(dbgs() << " *** NOTE: cycle header found\n");
1910 TryBreak = true;
1911 }
1912
1913
1914 if (!TryBreak)
1915 LLVM_DEBUG(dbgs() << "Sinking along critical edge.\n");
1916 else {
1917
1918
1919
1920 bool Status = PostponeSplitCriticalEdge(MI, ParentBlock, SuccToSinkTo,
1921 BreakPHIEdge);
1922 if (!Status)
1923 LLVM_DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to "
1924 "break critical edge\n");
1925
1926 return false;
1927 }
1928 }
1929
1930 if (BreakPHIEdge) {
1931
1932
1933
1934 bool Status =
1935 PostponeSplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);
1936 if (!Status)
1937 LLVM_DEBUG(dbgs() << " *** PUNTING: Not legal or profitable to "
1938 "break critical edge\n");
1939
1940 return false;
1941 }
1942
1943
1947 LLVM_DEBUG(dbgs() << " *** Not sinking: prologue interference\n");
1948 return false;
1949 }
1950
1951
1953 for (auto &MO : MI.all_defs()) {
1955 continue;
1956 auto It = SeenDbgUsers.find(MO.getReg());
1957 if (It == SeenDbgUsers.end())
1958 continue;
1959
1960
1961 auto &Users = It->second;
1962 for (auto &User : Users) {
1963 MachineInstr *DbgMI = User.getPointer();
1964 if (User.getInt()) {
1965
1966
1969 } else {
1972 }
1973 }
1974 }
1975
1976
1977
1978
1979 if (MI.getMF()->getFunction().getSubprogram() && MI.isCopy())
1980 SalvageUnsunkDebugUsersOfCopy(MI, SuccToSinkTo);
1981
1982 performSink(MI, *SuccToSinkTo, InsertPos, DbgUsersToSink);
1983
1984
1985
1986
1987
1988
1989 for (MachineOperand &MO : MI.all_uses())
1990 RegsToClearKillFlags.insert(MO.getReg());
1991
1992 return true;
1993}
1994
1995void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1996 MachineInstr &MI, MachineBasicBlock *TargetBlock) {
1998 assert(MI.getOperand(1).isReg());
1999
2000
2001
2002
2003 SmallVector<MachineInstr *, 4> DbgDefUsers;
2005 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
2006 for (auto &MO : MI.all_defs()) {
2008 continue;
2010 for (auto &User : MRI.use_instructions(MO.getReg())) {
2011 if (.isDebugValue() || DT->dominates(TargetBlock, User.getParent()))
2012 continue;
2013
2014
2015 if (User.getParent() == MI.getParent())
2016 continue;
2017
2019 "DBG_VALUE user of vreg, but has no operand for it?");
2021 }
2022 }
2023
2024
2025
2026 for (auto *User : DbgDefUsers) {
2027 for (auto &Reg : DbgUseRegs) {
2028 for (auto &DbgOp : User->getDebugOperandsForReg(Reg)) {
2029 DbgOp.setReg(MI.getOperand(1).getReg());
2030 DbgOp.setSubReg(MI.getOperand(1).getSubReg());
2031 }
2032 }
2033 }
2034}
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070namespace {
2071
2072class PostRAMachineSinkingImpl {
2073
2074 LiveRegUnits ModifiedRegUnits, UsedRegUnits;
2075
2076
2077
2078
2079
2080 DenseMap<MCRegUnit, SmallVector<MIRegs, 2>> SeenDbgInstrs;
2081
2082
2083
2084 bool tryToSinkCopy(MachineBasicBlock &BB, MachineFunction &MF,
2085 const TargetRegisterInfo *TRI, const TargetInstrInfo *TII);
2086
2087public:
2088 bool run(MachineFunction &MF);
2089};
2090
2091class PostRAMachineSinkingLegacy : public MachineFunctionPass {
2092public:
2093 bool runOnMachineFunction(MachineFunction &MF) override;
2094
2095 static char ID;
2096 PostRAMachineSinkingLegacy() : MachineFunctionPass(ID) {}
2097 StringRef getPassName() const override { return "PostRA Machine Sink"; }
2098
2099 void getAnalysisUsage(AnalysisUsage &AU) const override {
2102 }
2103
2104 MachineFunctionProperties getRequiredProperties() const override {
2105 return MachineFunctionProperties().setNoVRegs();
2106 }
2107};
2108
2109}
2110
2111char PostRAMachineSinkingLegacy::ID = 0;
2113
2115 "PostRA Machine Sink", false, false)
2116
2122}
2123
2124static MachineBasicBlock *
2128
2130 for (auto *SI : SinkableBBs) {
2131 if (aliasWithRegsInLiveIn(*SI, Reg, TRI)) {
2132
2133
2134 if (BB)
2135 return nullptr;
2136 BB = SI;
2137 }
2138 }
2139
2140 if (!BB)
2141 return nullptr;
2142
2143
2145 if (!SinkableBBs.count(SI) && aliasWithRegsInLiveIn(*SI, Reg, TRI))
2146 return nullptr;
2147 }
2148 return BB;
2149}
2150
2151static MachineBasicBlock *
2157 for (auto DefReg : DefedRegsInCopy) {
2160 if (!BB || (SingleBB && SingleBB != BB))
2161 return nullptr;
2162 SingleBB = BB;
2163 }
2164 return SingleBB;
2165}
2166
2171 for (auto U : UsedOpsInCopy) {
2174 if (!UsedRegUnits.available(SrcReg)) {
2177 if (UI.killsRegister(SrcReg, TRI)) {
2178 UI.clearRegisterKills(SrcReg, TRI);
2180 break;
2181 }
2182 }
2183 }
2184 }
2185}
2186
2190 for (Register DefReg : DefedRegsInCopy)
2192
2193 for (auto U : UsedOpsInCopy)
2194 SuccBB->addLiveIn(MI->getOperand(U).getReg());
2196}
2197
2203 bool HasRegDependency = false;
2204 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
2206 if (!MO.isReg())
2207 continue;
2209 if ()
2210 continue;
2211 if (MO.isDef()) {
2213 HasRegDependency = true;
2214 break;
2215 }
2217
2218
2219
2220
2221
2222 } else if (MO.isUse()) {
2224 HasRegDependency = true;
2225 break;
2226 }
2228 }
2229 }
2230 return HasRegDependency;
2231}
2232
2233bool PostRAMachineSinkingImpl::tryToSinkCopy(MachineBasicBlock &CurBB,
2234 MachineFunction &MF,
2235 const TargetRegisterInfo *TRI,
2236 const TargetInstrInfo *TII) {
2237 SmallPtrSet<MachineBasicBlock *, 2> SinkableBBs;
2238
2239
2240
2241 for (MachineBasicBlock *SI : CurBB.successors())
2242 if (->livein_empty() && SI->pred_size() == 1)
2243 SinkableBBs.insert(SI);
2244
2245 if (SinkableBBs.empty())
2246 return false;
2247
2249
2250
2251
2252 ModifiedRegUnits.clear();
2253 UsedRegUnits.clear();
2254 SeenDbgInstrs.clear();
2255
2257
2258 SmallVector<unsigned, 2> UsedOpsInCopy;
2259
2261
2262
2263
2264 if (MI.isDebugValue() && .isDebugRef()) {
2265 SmallDenseMap<MCRegUnit, SmallVector<Register, 2>, 4> MIUnits;
2266 bool IsValid = true;
2267 for (MachineOperand &MO : MI.debug_operands()) {
2269
2270
2272 ModifiedRegUnits, UsedRegUnits)) {
2273 IsValid = false;
2274 break;
2275 }
2276
2277
2278 for (MCRegUnit Unit : TRI->regunits(MO.getReg()))
2279 MIUnits[Unit].push_back(MO.getReg());
2280 }
2281 }
2282 if (IsValid) {
2283 for (auto &RegOps : MIUnits)
2284 SeenDbgInstrs[RegOps.first].emplace_back(&MI,
2285 std::move(RegOps.second));
2286 }
2287 continue;
2288 }
2289
2290
2292 continue;
2293
2294 if (MI.isDebugOrPseudoInstr())
2295 continue;
2296
2297
2298 if (MI.isCall())
2299 return false;
2300
2301 if (.isCopy() ||
.getOperand(0).isRenamable()) {
2304 continue;
2305 }
2306
2307
2309 ModifiedRegUnits, UsedRegUnits)) {
2312 continue;
2313 }
2314 assert((!UsedOpsInCopy.empty() && !DefedRegsInCopy.empty()) &&
2315 "Unexpect SrcReg or DefReg");
2316 MachineBasicBlock *SuccBB =
2318
2319
2320 if (!SuccBB) {
2323 continue;
2324 }
2326 "Unexpected predecessor");
2327
2328
2329
2330
2331 MapVector<MachineInstr *, MIRegs::second_type> DbgValsToSinkMap;
2332 for (auto &MO : MI.all_defs()) {
2333 for (MCRegUnit Unit : TRI->regunits(MO.getReg())) {
2334 for (const auto &MIRegs : SeenDbgInstrs.lookup(Unit)) {
2335 auto &Regs = DbgValsToSinkMap[MIRegs.first];
2337 }
2338 }
2339 }
2340 auto DbgValsToSink = DbgValsToSinkMap.takeVector();
2341
2342 LLVM_DEBUG(dbgs() << "Sink instr " << MI << "\tinto block " << *SuccBB);
2343
2349 LLVM_DEBUG(dbgs() << " *** Not sinking: prologue interference\n");
2350 continue;
2351 }
2352
2353
2354
2356 performSink(MI, *SuccBB, InsertPos, DbgValsToSink);
2357 updateLiveIn(&MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy);
2358
2360 ++NumPostRACopySink;
2361 }
2363}
2364
2365bool PostRAMachineSinkingImpl::run(MachineFunction &MF) {
2369
2370 ModifiedRegUnits.init(*TRI);
2372 for (auto &BB : MF)
2374
2376}
2377
2378bool PostRAMachineSinkingLegacy::runOnMachineFunction(MachineFunction &MF) {
2380 return false;
2381
2382 return PostRAMachineSinkingImpl().run(MF);
2383}
2384
2385PreservedAnalyses
2389
2390 if (!PostRAMachineSinkingImpl().run(MF))
2392
2395 return PA;
2396}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static const HTTPClientCleanup Cleanup
static Register UseReg(const MachineOperand &MO)
iv Induction Variable Users
static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI)
Return true if this machine instruction loads from global offset table or constant pool.
static cl::opt< unsigned > SinkLoadInstsPerBlockThreshold("machine-sink-load-instrs-threshold", cl::desc("Do not try to find alias store for a load if there is a in-path " "block whose instruction number is higher than this threshold."), cl::init(2000), cl::Hidden)
static cl::opt< unsigned > SinkIntoCycleLimit("machine-sink-cycle-limit", cl::desc("The maximum number of instructions considered for cycle sinking."), cl::init(50), cl::Hidden)
TargetInstrInfo::RegSubRegPair RegSubRegPair
Definition MachineSink.cpp:122
Register Reg
Definition MachineSink.cpp:2117
static void clearKillFlags(MachineInstr *MI, MachineBasicBlock &CurBB, const SmallVectorImpl< unsigned > &UsedOpsInCopy, const LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
Definition MachineSink.cpp:2167
static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo, MachineBasicBlock::iterator InsertPos, ArrayRef< MIRegs > DbgValuesToSink)
Sink an instruction and its associated debug instructions.
Definition MachineSink.cpp:1608
static cl::opt< bool > SplitEdges("machine-sink-split", cl::desc("Split critical edges during machine sinking"), cl::init(true), cl::Hidden)
static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
Return true if MI is likely to be usable as a memory operation by the implicit null check optimizatio...
Definition MachineSink.cpp:1511
static cl::opt< bool > SinkInstsIntoCycle("sink-insts-to-avoid-spills", cl::desc("Sink instructions into cycles to avoid " "register spills"), cl::init(false), cl::Hidden)
static cl::opt< unsigned > SinkLoadBlocksThreshold("machine-sink-load-blocks-threshold", cl::desc("Do not try to find alias store for a load if the block number in " "the straight line is higher than this threshold."), cl::init(20), cl::Hidden)
static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB, const SmallVectorImpl< unsigned > &UsedOpsInCopy, const SmallVectorImpl< Register > &DefedRegsInCopy)
Definition MachineSink.cpp:2187
static bool hasRegisterDependency(MachineInstr *MI, SmallVectorImpl< unsigned > &UsedOpsInCopy, SmallVectorImpl< Register > &DefedRegsInCopy, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits)
Definition MachineSink.cpp:2198
Register const TargetRegisterInfo * TRI
Definition MachineSink.cpp:2118
std::pair< MachineInstr *, SmallVector< Register, 2 > > MIRegs
Definition MachineSink.cpp:1606
Machine code static false bool blockPrologueInterferes(const MachineBasicBlock *BB, MachineBasicBlock::const_iterator End, const MachineInstr &MI, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, const MachineRegisterInfo *MRI)
Return true if a target defined block prologue instruction interferes with a sink candidate.
Definition MachineSink.cpp:336
static cl::opt< unsigned > SplitEdgeProbabilityThreshold("machine-sink-split-probability-threshold", cl::desc("Percentage threshold for splitting single-instruction critical edge. " "If the branch threshold is higher than this threshold, we allow " "speculative execution of up to 1 instruction to avoid branching to " "splitted critical edge"), cl::init(40), cl::Hidden)
static bool attemptDebugCopyProp(MachineInstr &SinkInst, MachineInstr &DbgMI, Register Reg)
If the sunk instruction is a copy, try to forward the copy instead of leaving an 'undef' DBG_VALUE in...
Definition MachineSink.cpp:1556
static cl::opt< bool > UseBlockFreqInfo("machine-sink-bfi", cl::desc("Use block frequency info to find successors to sink"), cl::init(true), cl::Hidden)
static MachineBasicBlock * getSingleLiveInSuccBB(MachineBasicBlock &CurBB, const SmallPtrSetImpl< MachineBasicBlock * > &SinkableBBs, Register Reg, const TargetRegisterInfo *TRI)
Definition MachineSink.cpp:2125
This file implements a map that provides insertion order iteration.
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
Remove Loads Into Fake Uses
This file implements a set that has insertion order iteration characteristics.
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
static bool SinkInstruction(Instruction *Inst, SmallPtrSetImpl< Instruction * > &Stores, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
SinkInstruction - Determine whether it is safe to sink the specified machine instruction out of its c...
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Target-Independent Code Generator Pass Configuration Options pass.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
Represents analyses that only rely on functions' control flow.
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
iterator_range< const_toplevel_iterator > toplevel_cycles() const
void splitCriticalEdge(BlockT *Pred, BlockT *Succ, BlockT *New)
unsigned getCycleDepth(const BlockT *Block) const
get the depth for the cycle which containing a given block.
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
BlockT * getHeader() const
bool isReducible() const
Whether the cycle is a natural loop.
BlockT * getCyclePreheader() const
Return the preheader block for this cycle.
bool contains(const BlockT *Block) const
Return whether Block is contained in the cycle.
Module * getParent()
Get the module that this global value is contained inside of...
A set of register units used to track register liveness.
static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
void init(const TargetRegisterInfo &TRI)
Initialize and clear the set.
LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB)
Adds registers living into block MBB.
void clear()
Clears the set.
An RAII based helper class to modify MachineFunctionProperties when running pass.
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
unsigned pred_size() const
bool isEHPad() const
Returns true if the block is a landing pad.
instr_iterator instr_begin()
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
unsigned succ_size() const
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
pred_iterator pred_begin()
LLVM_ABI void removeLiveInOverlappedWith(MCRegister Reg)
Remove the specified register from any overlapped live in.
instr_iterator instr_end()
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
LLVM_ABI void onEdgeSplit(const MachineBasicBlock &NewPredecessor, const MachineBasicBlock &NewSuccessor, const MachineBranchProbabilityInfo &MBPI)
incrementally calculate block frequencies when we split edges, to avoid full CFG traversal.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Legacy analysis pass which computes a MachineCycleInfo.
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
bool hasDebugOperandForReg(Register Reg) const
Returns whether this debug value has at least one debug operand with the register Reg.
void setDebugValueUndef()
Sets all register debug operands in this debug value instruction to be undef.
LLVM_ABI iterator_range< filter_iterator< const MachineOperand *, std::function< bool(const MachineOperand &Op)> > > getDebugOperandsForReg(Register Reg) const
Returns a range of all of the operands that correspond to a debug use of Reg.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isCopyLike() const
Return true if the instruction behaves like a copy.
bool isDebugInstr() const
LLVM_ABI void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
const MachineOperand & getOperand(unsigned i) const
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Analysis pass that exposes the MachineLoopInfo for a machine function.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)
Definition MachineSink.cpp:757
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Definition MachineSink.cpp:787
VectorType takeVector()
Clear the MapVector and return the underlying vector.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PointerIntPair - This class implements a pair of a pointer and small integer.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition MachineSink.cpp:2386
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Special value supplied for machine level alias analysis.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A vector that has set insertion semantics.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool isBasicBlockPrologue(const MachineInstr &MI, Register Reg=Register()) const
True if the instruction is bound to the top of its basic block and no other instructions shall be ins...
virtual bool hasLowDefLatency(const TargetSchedModel &SchedModel, const MachineInstr &DefMI, unsigned DefIdx) const
Compute operand latency of a def of 'Reg'.
virtual bool isSafeToSink(MachineInstr &MI, MachineBasicBlock *SuccToSinkTo, MachineCycleInfo *CI) const
virtual bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const
Check if it's possible and beneficial to fold the addressing computation AddrI into the addressing mo...
virtual bool shouldBreakCriticalEdgeToSink(MachineInstr &MI) const
For a "cheap" instruction which doesn't enable additional sinking, should MachineSink break a critica...
virtual bool isIgnorableUse(const MachineOperand &MO) const
Given MO is a PhysReg use return if it can be ignored for the purpose of instruction rematerializatio...
virtual bool shouldPostRASink(const MachineInstr &MI) const
virtual bool isAsCheapAsAMove(const MachineInstr &MI) const
Return true if the instruction is as cheap as a move instruction.
virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, unsigned SubIdx, const MachineInstr &Orig) const
Re-issue the specified 'original' instruction at the specific location targeting a new destination re...
virtual bool shouldSink(const MachineInstr &MI) const
Return true if the instruction should be sunk by MachineSink.
virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const
Return true if it's safe to move a machine instruction that defines the specified register class.
virtual MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const
Emit a load/store instruction with the same value register as MemI, but using the address from AM.
Target-Independent Code Generator Pass Configuration Options.
bool getEnableSinkAndFold() const
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
bool hasSuperClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Abstract Attribute helper functions.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
LLVM_ABI void initializeMachineSinkingLegacyPass(PassRegistry &)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI bool isCycleInvariant(const MachineCycle *Cycle, MachineInstr &I)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
Definition MachineSink.cpp:2112
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI char & MachineSinkingLegacyID
MachineSinking - This pass performs sinking on machine instructions.
Definition MachineSink.cpp:322
iterator_range< df_iterator< T > > depth_first(const T &G)
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
GenericCycleInfo< MachineSSAContext > MachineCycleInfo
MachineCycleInfo::CycleT MachineCycle
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Represents a predicate at the MachineFunction level.
A pair composed of a register and a sub-register index.