LLVM: lib/CodeGen/EarlyIfConversion.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
41
42using namespace llvm;
43
44#define DEBUG_TYPE "early-ifcvt"
45
46
47
50 cl::desc("Maximum number of instructions per speculated block."));
51
52
54 cl::desc("Turn all knobs to 11"));
55
56STATISTIC(NumDiamondsSeen, "Number of diamonds");
57STATISTIC(NumDiamondsConv, "Number of diamonds converted");
58STATISTIC(NumTrianglesSeen, "Number of triangles");
59STATISTIC(NumTrianglesConv, "Number of triangles converted");
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82namespace {
83class SSAIfConv {
87
88public:
89
91
92
94
95
97
98
100
101
102
103 bool isTriangle() const { return TBB == Tail || FBB == Tail; }
104
105
107
108
110
111
112 struct PHIInfo {
114 unsigned TReg = 0, FReg = 0;
115
116 int CondCycles = 0, TCycles = 0, FCycles = 0;
117
119 };
120
122
123
125
126private:
127
128
130
131
133
134
136
137
138
140
141
142
144
145
146
148
149
150
151 bool InstrDependenciesAllowIfConv(MachineInstr *I);
152
153
154
156
157
158 bool findInsertionPoint();
159
160
161 void replacePHIInstrs();
162
163
164 void rewritePHIOperands();
165
166public:
167
174 ClobberedRegUnits.clear();
175 ClobberedRegUnits.resize(TRI->getNumRegUnits());
176 }
177
178
179
180
181
183
184
185
187 bool Predicate = false);
188};
189}
190
191
192
193
194
195
196
197
198
200
201
204 return false;
205 }
206
208
209
210
213 if (MI.isDebugInstr())
214 continue;
215
219 return false;
220 }
221
222
223 if (MI.isPHI()) {
225 return false;
226 }
227
228
229
230
231 if (MI.mayLoad()) {
233 return false;
234 }
235
236
237 bool DontMoveAcrossStore = true;
238 if (.isSafeToMove(DontMoveAcrossStore)) {
240 return false;
241 }
242
243
244 if (!InstrDependenciesAllowIfConv(&MI))
245 return false;
246 }
247 return true;
248}
249
250
251
252
253
254bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *I) {
256 if (MO.isRegMask()) {
258 return false;
259 }
260 if (!MO.isReg())
261 continue;
263
264
265 if (MO.isDef() && Reg.isPhysical())
267 ClobberedRegUnits.set(Unit);
268
269 if (!MO.readsReg() || .isVirtual())
270 continue;
273 continue;
278 LLVM_DEBUG(dbgs() << "Can't insert instructions below terminator.\n");
279 return false;
280 }
281 }
282 return true;
283}
284
285
286
287
288
289
290
291
292
294
295
298 return false;
299 }
300
302
303
304
308 if (I->isDebugInstr())
309 continue;
310
314 return false;
315 }
316
317
318 if (I->isPHI()) {
320 return false;
321 }
322
323
326 return false;
327 }
328
329
332 return false;
333 }
334
335
336 if (!InstrDependenciesAllowIfConv(&(*I)))
337 return false;
338 }
339 return true;
340}
341
342
343void SSAIfConv::PredicateBlock(MachineBasicBlock *MBB, bool ReversePredicate) {
344 auto Condition = Cond;
345 if (ReversePredicate) {
347 assert(CanRevCond && "Reversed predicate is not supported");
348 (void)CanRevCond;
349 }
350
354 if (I->isDebugInstr())
355 continue;
357 }
358}
359
360
361
362
363
364
365
366
367
368
369
370bool SSAIfConv::findInsertionPoint() {
371
372
379 --I;
380
381 if (InsertAfter.count(&*I)) {
383 return false;
384 }
385
386
388
389 if (!MO.isReg())
390 continue;
392 if (.isPhysical())
393 continue;
394
395 if (MO.isDef())
398
399 if (MO.readsReg())
401 }
402
403 while (!Reads.empty())
405 if (ClobberedRegUnits.test(Unit))
407
408
409 if (I != FirstTerm && I->isTerminator())
410 continue;
411
412
413
416 dbgs() << "Would clobber";
419 dbgs() << " live before " << *I;
420 });
421 continue;
422 }
423
424
427 return true;
428 }
429 LLVM_DEBUG(dbgs() << "No legal insertion point found.\n");
430 return false;
431}
432
433
434
435
436
437
439 Head = MBB;
440 TBB = FBB = Tail = nullptr;
441
443 return false;
446
447
450
452 return false;
453
455
456
457 if (Tail != Succ1) {
458
461 return false;
466
467
468 if (->livein_empty()) {
470 return false;
471 }
472 } else {
476 }
477
478
479
480
481 if (!Predicate && (Tail->empty() || ->front().isPHI())) {
483 return false;
484 }
485
486
487 Cond.clear();
490 return false;
491 }
492
493
494 if () {
495 LLVM_DEBUG(dbgs() << "analyzeBranch didn't find conditional branch.\n");
496 return false;
497 }
498
499
500
501 if (Cond.empty()) {
502 LLVM_DEBUG(dbgs() << "analyzeBranch found an unconditional branch.\n");
503 return false;
504 }
505
506
507
508 FBB = TBB == Succ0 ? Succ1 : Succ0;
509
510
515 I != E && I->isPHI(); ++I) {
517 PHIInfo &PI = PHIs.back();
518
519 for (unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
520 if (PI.PHI->getOperand(i+1).getMBB() == TPred)
521 PI.TReg = PI.PHI->getOperand(i).getReg();
522 if (PI.PHI->getOperand(i+1).getMBB() == FPred)
523 PI.FReg = PI.PHI->getOperand(i).getReg();
524 }
527
528
529 if (->canInsertSelect(*Head, Cond, PI.PHI->getOperand(0).getReg(),
530 PI.TReg, PI.FReg, PI.CondCycles, PI.TCycles,
531 PI.FCycles)) {
533 return false;
534 }
535 }
536
537
538 InsertAfter.clear();
539 ClobberedRegUnits.reset();
540 if (Predicate) {
541 if (TBB != Tail && !canPredicateInstrs(TBB))
542 return false;
543 if (FBB != Tail && !canPredicateInstrs(FBB))
544 return false;
545 } else {
546 if (TBB != Tail && !canSpeculateInstrs(TBB))
547 return false;
548 if (FBB != Tail && !canSpeculateInstrs(FBB))
549 return false;
550 }
551
552
553
554 if (!findInsertionPoint())
555 return false;
556
557 if (isTriangle())
558 ++NumTrianglesSeen;
559 else
560 ++NumDiamondsSeen;
561 return true;
562}
563
564
568 if (TReg == FReg)
569 return true;
570
572 return false;
573
576 if (!TDef || !FDef)
577 return false;
578
579
581 return false;
582
583
584
586 return false;
587
588
589
590
591
593 return MO.isReg() && MO.getReg().isPhysical();
594 }))
595 return false;
596
597
598 if (->produceSameValue(*TDef, *FDef, &MRI))
599 return false;
600
601
604 if (TIdx == -1 || FIdx == -1)
605 return false;
606
607 return TIdx == FIdx;
608}
609
610
611
612
613void SSAIfConv::replacePHIInstrs() {
614 assert(Tail->pred_size() == 2 && "Cannot replace PHIs");
616 assert(FirstTerm != Head->end() && "No terminators");
617 DebugLoc HeadDL = FirstTerm->getDebugLoc();
618
619
620 for (PHIInfo &PI : PHIs) {
622 Register DstReg = PI.PHI->getOperand(0).getReg();
624
625
626 BuildMI(*Head, FirstTerm, HeadDL, TII->get(TargetOpcode::COPY), DstReg)
628 } else {
629 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg,
630 PI.FReg);
631 }
632 LLVM_DEBUG(dbgs() << " --> " << *std::prev(FirstTerm));
633 PI.PHI->eraseFromParent();
634 PI.PHI = nullptr;
635 }
636}
637
638
639
640
641void SSAIfConv::rewritePHIOperands() {
643 assert(FirstTerm != Head->end() && "No terminators");
644 DebugLoc HeadDL = FirstTerm->getDebugLoc();
645
646
647 for (PHIInfo &PI : PHIs) {
648 unsigned DstReg = 0;
649
652
653
654 DstReg = PI.TReg;
655 } else {
656 Register PHIDst = PI.PHI->getOperand(0).getReg();
657 DstReg = MRI->createVirtualRegister(MRI->getRegClass(PHIDst));
658 TII->insertSelect(*Head, FirstTerm, HeadDL,
659 DstReg, Cond, PI.TReg, PI.FReg);
660 LLVM_DEBUG(dbgs() << " --> " << *std::prev(FirstTerm));
661 }
662
663
664 for (unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
666 if (MBB == getTPred()) {
667 PI.PHI->getOperand(i-1).setMBB(Head);
668 PI.PHI->getOperand(i-2).setReg(DstReg);
669 } else if (MBB == getFPred()) {
670 PI.PHI->removeOperand(i-1);
671 PI.PHI->removeOperand(i-2);
672 }
673 }
675 }
676}
677
678
679
680
681
682
684 bool Predicate) {
685 assert(Head && Tail && TBB && FBB && "Call canConvertIf first.");
686
687
688 if (isTriangle())
689 ++NumTrianglesConv;
690 else
691 ++NumDiamondsConv;
692
693
695 if (Predicate)
696 PredicateBlock(TBB, false);
698 }
699 if (FBB != Tail) {
700 if (Predicate)
701 PredicateBlock(FBB, true);
703 }
704
705 bool ExtraPreds = Tail->pred_size() != 2;
706 if (ExtraPreds)
707 rewritePHIOperands();
708 else
709 replacePHIInstrs();
710
711
716 if (FBB != Tail)
718
719
720
723
724
725
726
731 }
732 if (FBB != Tail) {
736 }
737
740
747 if (Tail != &Tail->getParent()->back())
748 Tail->moveAfter(&Tail->getParent()->back());
749 } else {
750
751 LLVM_DEBUG(dbgs() << "Converting to unconditional branch.\n");
755 }
757}
758
759
760
761
762
763namespace {
764class EarlyIfConverter {
773 SSAIfConv IfConv;
774
775public:
778 : DomTree(&DT), Loops(&LI), Traces(&MTM) {}
779 EarlyIfConverter() = delete;
780
782
783private:
785 void invalidateTraces();
786 bool shouldConvertIf();
787};
788
790public:
791 static char ID;
796};
797}
798
799char EarlyIfConverterLegacy::ID = 0;
801
803 false, false)
809
810void EarlyIfConverterLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
819}
820
821namespace {
822
825
826
827
829 for (auto *B : Removed) {
831 assert(Node != HeadNode && "Cannot erase the head node");
832 while (Node->getNumChildren()) {
833 assert(Node->getBlock() == IfConv.Tail && "Unexpected children");
835 }
837 }
838}
839
840
843
844
845 for (auto *B : Removed)
847}
848}
849
850
851void EarlyIfConverter::invalidateTraces() {
852 Traces->verifyAnalysis();
853 Traces->invalidate(IfConv.Head);
854 Traces->invalidate(IfConv.Tail);
855 Traces->invalidate(IfConv.TBB);
856 Traces->invalidate(IfConv.FBB);
857 Traces->verifyAnalysis();
858}
859
860
861static unsigned adjCycles(unsigned Cyc, int Delta) {
862 if (Delta < 0 && Cyc + Delta > Cyc)
863 return 0;
864 return Cyc + Delta;
865}
866
867namespace {
868
869struct Cycles {
870 const char *Key;
872};
874 return R << ore::NV(C.Key, C.Value) << (C.Value == 1 ? " cycle" : " cycles");
875}
876}
877
878
879
880
881bool EarlyIfConverter::shouldConvertIf() {
882
884 return true;
885
886
887
889
890
891
892
893
895 if (!MO.isReg() || !MO.isUse())
896 return false;
897 Register Reg = MO.getReg();
898 if (Reg.isPhysical())
899 return false;
900
901 MachineInstr *Def = MRI->getVRegDef(Reg);
902 return CurrentLoop->isLoopInvariant(*Def) ||
903 all_of(Def->operands(), [&](MachineOperand &Op) {
904 if (Op.isImm())
905 return true;
906 if (!MO.isReg() || !MO.isUse())
907 return false;
908 Register Reg = MO.getReg();
909 if (Reg.isPhysical())
910 return false;
911
912 MachineInstr *Def = MRI->getVRegDef(Reg);
913 return CurrentLoop->isLoopInvariant(*Def);
914 });
915 }))
916 return false;
917
918 if (!MinInstr)
919 MinInstr = Traces->getEnsemble(MachineTraceStrategy::TS_MinInstrCount);
920
923 LLVM_DEBUG(dbgs() << "TBB: " << TBBTrace << "FBB: " << FBBTrace);
926
927
928 unsigned CritLimit = SchedModel.MispredictPenalty/2;
929
932
933
934
935
937 if (IfConv.TBB != IfConv.Tail)
938 ExtraBlocks.push_back(IfConv.TBB);
941 << ", minimal critical path " << MinCrit << '\n');
942 if (ResLength > MinCrit + CritLimit) {
944 MORE.emit([&]() {
947 R << "did not if-convert branch: the resulting critical path ("
948 << Cycles{"ResLength", ResLength}
949 << ") would extend the shorter leg's critical path ("
950 << Cycles{"MinCrit", MinCrit} << ") by more than the threshold of "
951 << Cycles{"CritLimit", CritLimit}
952 << ", which cannot be hidden by available ILP.";
953 return R;
954 });
955 return false;
956 }
957
958
959
960
962 unsigned BranchDepth =
964 LLVM_DEBUG(dbgs() << "Branch depth: " << BranchDepth << '\n');
965
966
967
969 struct CriticalPathInfo {
970 unsigned Extra;
971 unsigned Depth;
972 };
973 CriticalPathInfo Cond{};
974 CriticalPathInfo TBlock{};
975 CriticalPathInfo FBlock{};
976 bool ShouldConvert = true;
977 for (SSAIfConv::PHIInfo &PI : IfConv.PHIs) {
978 unsigned Slack = TailTrace.getInstrSlack(*PI.PHI);
980 LLVM_DEBUG(dbgs() << "Slack " << Slack << ":\t" << *PI.PHI);
981
982
983 unsigned CondDepth = adjCycles(BranchDepth, PI.CondCycles);
984 if (CondDepth > MaxDepth) {
985 unsigned Extra = CondDepth - MaxDepth;
986 LLVM_DEBUG(dbgs() << "Condition adds " << Extra << " cycles.\n");
987 if (Extra > Cond.Extra)
988 Cond = {Extra, CondDepth};
989 if (Extra > CritLimit) {
990 LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
991 ShouldConvert = false;
992 }
993 }
994
995
997 if (TDepth > MaxDepth) {
998 unsigned Extra = TDepth - MaxDepth;
999 LLVM_DEBUG(dbgs() << "TBB data adds " << Extra << " cycles.\n");
1000 if (Extra > TBlock.Extra)
1001 TBlock = {Extra, TDepth};
1002 if (Extra > CritLimit) {
1003 LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
1004 ShouldConvert = false;
1005 }
1006 }
1007
1008
1010 if (FDepth > MaxDepth) {
1011 unsigned Extra = FDepth - MaxDepth;
1012 LLVM_DEBUG(dbgs() << "FBB data adds " << Extra << " cycles.\n");
1013 if (Extra > FBlock.Extra)
1014 FBlock = {Extra, FDepth};
1015 if (Extra > CritLimit) {
1016 LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
1017 ShouldConvert = false;
1018 }
1019 }
1020 }
1021
1022
1023
1024
1025 const CriticalPathInfo Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
1026 const CriticalPathInfo Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
1027
1028 if (ShouldConvert) {
1029 MORE.emit([&]() {
1032 R << "performing if-conversion on branch: the condition adds "
1033 << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
1034 if (Short.Extra > 0)
1035 R << ", and the short leg adds another "
1036 << Cycles{"ShortCycles", Short.Extra};
1037 if (Long.Extra > 0)
1038 R << ", and the long leg adds another "
1039 << Cycles{"LongCycles", Long.Extra};
1040 R << ", each staying under the threshold of "
1041 << Cycles{"CritLimit", CritLimit} << ".";
1042 return R;
1043 });
1044 } else {
1045 MORE.emit([&]() {
1048 R << "did not if-convert branch: the condition would add "
1049 << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
1050 if (Cond.Extra > CritLimit)
1051 R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
1052 if (Short.Extra > 0) {
1053 R << ", and the short leg would add another "
1054 << Cycles{"ShortCycles", Short.Extra};
1055 if (Short.Extra > CritLimit)
1056 R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
1057 }
1058 if (Long.Extra > 0) {
1059 R << ", and the long leg would add another "
1060 << Cycles{"LongCycles", Long.Extra};
1061 if (Long.Extra > CritLimit)
1062 R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
1063 }
1064 R << ".";
1065 return R;
1066 });
1067 }
1068
1069 return ShouldConvert;
1070}
1071
1072
1073
1075 bool Changed = false;
1076 while (IfConv.canConvertIf(MBB) && shouldConvertIf()) {
1077
1078 invalidateTraces();
1080 IfConv.convertIf(RemoveBlocks);
1081 Changed = true;
1082 updateDomTree(DomTree, IfConv, RemoveBlocks);
1085 updateLoops(Loops, RemoveBlocks);
1086 }
1087 return Changed;
1088}
1089
1091 LLVM_DEBUG(dbgs() << "********** EARLY IF-CONVERSION **********\n"
1092 << "********** Function: " << MF.getName() << '\n');
1093
1094
1097 return false;
1098
1103 MinInstr = nullptr;
1104
1105 bool Changed = false;
1106 IfConv.init(MF);
1107
1108
1109
1110
1111
1112 for (auto *DomNode : post_order(DomTree))
1113 if (tryConvertIf(DomNode->getBlock()))
1114 Changed = true;
1115
1116 return Changed;
1117}
1118
1125
1126 EarlyIfConverter Impl(MDT, LI, MTM);
1127 bool Changed = Impl.run(MF);
1128 if (!Changed)
1130
1135 return PA;
1136}
1137
1138bool EarlyIfConverterLegacy::runOnMachineFunction(MachineFunction &MF) {
1140 return false;
1141
1143 getAnalysis().getDomTree();
1144 MachineLoopInfo &LI = getAnalysis().getLI();
1146 getAnalysis().getMTM();
1147
1148 return EarlyIfConverter(MDT, LI, MTM).run(MF);
1149}
1150
1151
1152
1153
1154
1155namespace {
1164 SSAIfConv IfConv;
1165
1166public:
1167 static char ID;
1169 void getAnalysisUsage(AnalysisUsage &AU) const override;
1170 bool runOnMachineFunction(MachineFunction &MF) override;
1171 StringRef getPassName() const override { return "Early If-predicator"; }
1172
1173protected:
1175 bool shouldConvertIf();
1176};
1177}
1178
1179#undef DEBUG_TYPE
1180#define DEBUG_TYPE "early-if-predicator"
1181
1182char EarlyIfPredicator::ID = 0;
1184
1186 false, false)
1191
1192void EarlyIfPredicator::getAnalysisUsage(AnalysisUsage &AU) const {
1199}
1200
1201
1202bool EarlyIfPredicator::shouldConvertIf() {
1203 auto TrueProbability = MBPI->getEdgeProbability(IfConv.Head, IfConv.TBB);
1204 if (IfConv.isTriangle()) {
1206 (IfConv.TBB == IfConv.Tail) ? *IfConv.FBB : *IfConv.TBB;
1207
1208 unsigned ExtraPredCost = 0;
1209 unsigned Cycles = 0;
1211 unsigned NumCycles = SchedModel.computeInstrLatency(&I, false);
1212 if (NumCycles > 1)
1213 Cycles += NumCycles - 1;
1214 ExtraPredCost += TII->getPredicationCost(I);
1215 }
1216
1218 TrueProbability);
1219 }
1220 unsigned TExtra = 0;
1221 unsigned FExtra = 0;
1222 unsigned TCycle = 0;
1223 unsigned FCycle = 0;
1225 unsigned NumCycles = SchedModel.computeInstrLatency(&I, false);
1226 if (NumCycles > 1)
1227 TCycle += NumCycles - 1;
1228 TExtra += TII->getPredicationCost(I);
1229 }
1231 unsigned NumCycles = SchedModel.computeInstrLatency(&I, false);
1232 if (NumCycles > 1)
1233 FCycle += NumCycles - 1;
1234 FExtra += TII->getPredicationCost(I);
1235 }
1237 FCycle, FExtra, TrueProbability);
1238}
1239
1240
1241
1243 bool Changed = false;
1244 while (IfConv.canConvertIf(MBB, true) && shouldConvertIf()) {
1245
1247 IfConv.convertIf(RemoveBlocks, true);
1248 Changed = true;
1249 updateDomTree(DomTree, IfConv, RemoveBlocks);
1252 updateLoops(Loops, RemoveBlocks);
1253 }
1254 return Changed;
1255}
1256
1257bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
1258 LLVM_DEBUG(dbgs() << "********** EARLY IF-PREDICATOR **********\n"
1259 << "********** Function: " << MF.getName() << '\n');
1261 return false;
1262
1267 SchedModel.init(&STI);
1268 DomTree = &getAnalysis().getDomTree();
1269 Loops = &getAnalysis().getLI();
1270 MBPI = &getAnalysis().getMBPI();
1271
1272 bool Changed = false;
1273 IfConv.init(MF);
1274
1275
1276
1277
1278
1279 for (auto *DomNode : post_order(DomTree))
1280 if (tryConvertIf(DomNode->getBlock()))
1281 Changed = true;
1282
1283 return Changed;
1284}
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineInstrBuilder MachineInstrBuilder & DefMI
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static unsigned InstrCount
static bool hasSameValue(const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, Register TReg, Register FReg)
static unsigned adjCycles(unsigned Cyc, int Delta)
static cl::opt< bool > Stress("stress-early-ifcvt", cl::Hidden, cl::desc("Turn all knobs to 11"))
static cl::opt< unsigned > BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden, cl::desc("Maximum number of instructions per speculated block."))
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SparseSet class derived from the version described in Briggs,...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void clear()
clear - Removes all bits from the bitvector.
Base class for the actual dominator tree node.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
void eraseNode(NodeT *BB)
eraseNode - Removes a node from the dominator tree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Return true if it's profitable to predicate instructions with accumulated instruction latency of "Num...
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Cond) const override
Convert the instruction into a predicated instruction.
bool isPredicable(const MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
A set of register units used to track register liveness.
bool empty() const
Returns true if the set is empty.
void clear()
Clears the set.
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
unsigned pred_size() const
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
succ_iterator succ_begin()
bool livein_empty() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 '...
void moveAfter(MachineBasicBlock *NewBefore)
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...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & back() const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isDereferenceableInvariantLoad() const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
iterator_range< mop_iterator > uses()
Returns a range that includes all operands which may be register uses.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A trace ensemble is a collection of traces selected using the same strategy, for example 'minimum res...
A trace represents a plausible sequence of executed basic blocks that passes through the current basi...
unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks={}, ArrayRef< const MCSchedClassDesc * > ExtraInstrs={}, ArrayRef< const MCSchedClassDesc * > RemoveInstrs={}) const
Return the resource length of the trace.
InstrCycles getInstrCycles(const MachineInstr &MI) const
Return the depth and height of MI.
unsigned getInstrSlack(const MachineInstr &MI) const
Return the slack of MI.
unsigned getCriticalPath() const
Return the length of the (data dependency) critical path through the trace.
unsigned getPHIDepth(const MachineInstr &PHI) const
Return the Depth of a PHI instruction in a trace center block successor.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
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.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
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.
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.
SparseSet - Fast set implementation for objects that can be identified by small unsigned keys.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
virtual bool enableEarlyIfConversion() const
Enable the use of the early if conversion pass.
LLVM Value Representation.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
iterator_range< po_iterator< T > > post_order(const T &G)
char & EarlyIfConverterLegacyID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char & EarlyIfPredicatorID
EarlyIfPredicator - This pass performs if-conversion on SSA form by predicating if/else block and ins...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Machine model for scheduling, bundling, and heuristics.
unsigned Depth
Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...