LLVM: lib/CodeGen/IfConversion.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
47#include
48#include
49#include
50#include
51#include
52#include
53#include
54
55using namespace llvm;
56
57#define DEBUG_TYPE "if-converter"
58
59
79
80STATISTIC(NumSimple, "Number of simple if-conversions performed");
81STATISTIC(NumSimpleFalse, "Number of simple (F) if-conversions performed");
82STATISTIC(NumTriangle, "Number of triangle if-conversions performed");
83STATISTIC(NumTriangleRev, "Number of triangle (R) if-conversions performed");
84STATISTIC(NumTriangleFalse,"Number of triangle (F) if-conversions performed");
85STATISTIC(NumTriangleFRev, "Number of triangle (F/R) if-conversions performed");
86STATISTIC(NumDiamonds, "Number of diamond if-conversions performed");
87STATISTIC(NumForkedDiamonds, "Number of forked-diamond if-conversions performed");
88STATISTIC(NumIfConvBBs, "Number of if-converted blocks");
89STATISTIC(NumDupBBs, "Number of duplicated blocks");
90STATISTIC(NumUnpred, "Number of true blocks of diamonds unpredicated");
91
92namespace {
93
95 enum IfcvtKind {
96 ICNotClassfied,
97 ICSimpleFalse,
98 ICSimple,
99 ICTriangleFRev,
100 ICTriangleRev,
101 ICTriangleFalse,
102 ICTriangle,
103 ICDiamond,
104 ICForkedDiamond
105
106 };
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 struct BBInfo {
139 bool IsDone : 1;
140 bool IsBeingAnalyzed : 1;
141 bool IsAnalyzed : 1;
142 bool IsEnqueued : 1;
143 bool IsBrAnalyzable : 1;
144 bool IsBrReversible : 1;
145 bool HasFallThrough : 1;
146 bool IsUnpredicable : 1;
147 bool CannotBeCopied : 1;
148 bool ClobbersPred : 1;
149 unsigned NonPredSize = 0;
150 unsigned ExtraCost = 0;
151 unsigned ExtraCost2 = 0;
152 MachineBasicBlock *BB = nullptr;
153 MachineBasicBlock *TrueBB = nullptr;
154 MachineBasicBlock *FalseBB = nullptr;
157
158 BBInfo() : IsDone(false), IsBeingAnalyzed(false),
159 IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false),
160 IsBrReversible(false), HasFallThrough(false),
161 IsUnpredicable(false), CannotBeCopied(false),
162 ClobbersPred(false) {}
163 };
164
165
166
167
168
169
170
171
172
173
174
175
176 struct IfcvtToken {
177 BBInfo &BBI;
178 IfcvtKind Kind;
179 unsigned NumDups;
180 unsigned NumDups2;
181 bool NeedSubsumption : 1;
182 bool TClobbersPred : 1;
183 bool FClobbersPred : 1;
184
185 IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0,
186 bool tc = false, bool fc = false)
187 : BBI(b), Kind(k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
188 TClobbersPred(tc), FClobbersPred(fc) {}
189 };
190
191
192
193 std::vector BBAnalysis;
194 TargetSchedModel SchedModel;
195
196 const TargetLoweringBase *TLI = nullptr;
197 const TargetInstrInfo *TII = nullptr;
198 const TargetRegisterInfo *TRI = nullptr;
199 const MachineBranchProbabilityInfo *MBPI = nullptr;
200 MachineRegisterInfo *MRI = nullptr;
201
202 LivePhysRegs Redefs;
203
204 bool PreRegAlloc = true;
205 bool MadeChange = false;
206 int FnNum = -1;
207 std::function<bool(const MachineFunction &)> PredicateFtor;
208
209 public:
210 static char ID;
211
212 IfConverter(std::function<bool(const MachineFunction &)> Ftor = nullptr)
213 : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
215 }
216
217 void getAnalysisUsage(AnalysisUsage &AU) const override {
218 AU.addRequired();
219 AU.addRequired();
220 AU.addRequired();
222 }
223
224 bool runOnMachineFunction(MachineFunction &MF) override;
225
226 MachineFunctionProperties getRequiredProperties() const override {
227 return MachineFunctionProperties().setNoVRegs();
228 }
229
230 private:
231 bool reverseBranchCondition(BBInfo &BBI) const;
232 bool ValidSimple(BBInfo &TrueBBI, unsigned &Dups,
233 BranchProbability Prediction) const;
234 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
235 bool FalseBranch, unsigned &Dups,
236 BranchProbability Prediction) const;
237 bool CountDuplicatedInstructions(
240 unsigned &Dups1, unsigned &Dups2,
241 MachineBasicBlock &TBB, MachineBasicBlock &FBB,
242 bool SkipUnconditionalBranches) const;
243 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
244 unsigned &Dups1, unsigned &Dups2,
245 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const;
246 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
247 unsigned &Dups1, unsigned &Dups2,
248 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const;
249 void AnalyzeBranches(BBInfo &BBI);
250 void ScanInstructions(BBInfo &BBI,
253 bool BranchUnpredicable = false) const;
254 bool RescanInstructions(
257 BBInfo &TrueBBI, BBInfo &FalseBBI) const;
258 void AnalyzeBlock(MachineBasicBlock &MBB,
259 std::vector<std::unique_ptr> &Tokens);
260 bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl &Pred,
261 bool isTriangle = false, bool RevBranch = false,
262 bool hasCommonTail = false);
263 void AnalyzeBlocks(MachineFunction &MF,
264 std::vector<std::unique_ptr> &Tokens);
265 void InvalidatePreds(MachineBasicBlock &MBB);
266 bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
267 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
268 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
269 unsigned NumDups1, unsigned NumDups2,
270 bool TClobbersPred, bool FClobbersPred,
271 bool RemoveBranch, bool MergeAddEdges);
272 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
273 unsigned NumDups1, unsigned NumDups2,
274 bool TClobbers, bool FClobbers);
275 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
276 unsigned NumDups1, unsigned NumDups2,
277 bool TClobbers, bool FClobbers);
279 SmallVectorImpl &Cond,
280 SmallSet<MCRegister, 4> *LaterRedefs = nullptr);
281 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
282 SmallVectorImpl &Cond,
283 bool IgnoreBr = false);
284 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges = true);
285
286 bool MeetIfcvtSizeLimit(MachineBasicBlock &BB,
287 unsigned Cycle, unsigned Extra,
288 BranchProbability Prediction) const {
289 return Cycle > 0 && TII->isProfitableToIfCvt(BB, Cycle, Extra,
290 Prediction);
291 }
292
293 bool MeetIfcvtSizeLimit(BBInfo &TBBInfo, BBInfo &FBBInfo,
294 MachineBasicBlock &CommBB, unsigned Dups,
295 BranchProbability Prediction, bool Forked) const {
296 const MachineFunction &MF = *TBBInfo.BB->getParent();
302
303 unsigned Dups1 = 0, Dups2 = 0;
304 if (!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
305 *TBBInfo.BB, *FBBInfo.BB,
306 true))
307 llvm_unreachable("should already have been checked by ValidDiamond");
308
309 unsigned BranchBytes = 0;
310 unsigned CommonBytes = 0;
311
312
313 for (auto &I : make_range(TBBInfo.BB->begin(), TIB)) {
315 CommonBytes += TII->getInstSizeInBytes(I);
316 }
317 for (auto &I : make_range(FBBInfo.BB->begin(), FIB)) {
319 CommonBytes += TII->getInstSizeInBytes(I);
320 }
321
322
323
324
325
326 for (auto &I : make_range(TIE, TBBInfo.BB->end())) {
327 if (I.isBranch() && TBBInfo.IsBrAnalyzable && !Forked) {
329 BranchBytes += TII->predictBranchSizeForIfCvt(I);
330 } else {
332 CommonBytes += TII->getInstSizeInBytes(I);
333 }
334 }
335 for (auto &I : make_range(FIE, FBBInfo.BB->end())) {
336 if (I.isBranch() && FBBInfo.IsBrAnalyzable && !Forked) {
338 BranchBytes += TII->predictBranchSizeForIfCvt(I);
339 } else {
341 CommonBytes += TII->getInstSizeInBytes(I);
342 }
343 }
345 if (I.isBranch()) {
347 BranchBytes += TII->predictBranchSizeForIfCvt(I);
348 }
349 }
350
351
352
353 CommonBytes /= 2;
354
355
356 unsigned NumPredicatedInstructions = 0;
358 if (.isDebugInstr()) {
360 NumPredicatedInstructions++;
361 }
362 }
364 if (.isDebugInstr()) {
366 NumPredicatedInstructions++;
367 }
368 }
369
370
371
372 if (NumPredicatedInstructions > 15)
373 return false;
374
375
376
377 unsigned ExtraPredicateBytes = TII->extraSizeToPredicateInstructions(
378 MF, NumPredicatedInstructions);
379
380 LLVM_DEBUG(dbgs() << "MeetIfcvtSizeLimit(BranchBytes=" << BranchBytes
381 << ", CommonBytes=" << CommonBytes
382 << ", NumPredicatedInstructions="
383 << NumPredicatedInstructions
384 << ", ExtraPredicateBytes=" << ExtraPredicateBytes
385 << ")\n");
386 return (BranchBytes + CommonBytes) > ExtraPredicateBytes;
387 } else {
388 unsigned TCycle = TBBInfo.NonPredSize + TBBInfo.ExtraCost - Dups;
389 unsigned FCycle = FBBInfo.NonPredSize + FBBInfo.ExtraCost - Dups;
390 bool Res = TCycle > 0 && FCycle > 0 &&
391 TII->isProfitableToIfCvt(
392 *TBBInfo.BB, TCycle, TBBInfo.ExtraCost2, *FBBInfo.BB,
393 FCycle, FBBInfo.ExtraCost2, Prediction);
394 LLVM_DEBUG(dbgs() << "MeetIfcvtSizeLimit(TCycle=" << TCycle
395 << ", FCycle=" << FCycle
396 << ", TExtra=" << TBBInfo.ExtraCost2 << ", FExtra="
397 << FBBInfo.ExtraCost2 << ") = " << Res << "\n");
398 return Res;
399 }
400 }
401
402
403 bool blockAlwaysFallThrough(BBInfo &BBI) const {
404 return BBI.IsBrAnalyzable && BBI.TrueBB == nullptr;
405 }
406
407
408 bool blockNeverFallThrough(BBInfo &BBI) const {
409
410 if (BBI.IsBrAnalyzable)
411 return !BBI.HasFallThrough;
412
413
416 if (I == BBI.BB->getParent()->end() || !PI->isSuccessor(&*I))
417 return true;
418
419 return false;
420 }
421
422
423 static bool IfcvtTokenCmp(const std::unique_ptr &C1,
424 const std::unique_ptr &C2) {
425 int Incr1 = (C1->Kind == ICDiamond)
426 ? -(int)(C1->NumDups + C1->NumDups2) : (int)C1->NumDups;
427 int Incr2 = (C2->Kind == ICDiamond)
428 ? -(int)(C2->NumDups + C2->NumDups2) : (int)C2->NumDups;
429 if (Incr1 > Incr2)
430 return true;
431 else if (Incr1 == Incr2) {
432
433 if (!C1->NeedSubsumption && C2->NeedSubsumption)
434 return true;
435 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
436
437 if ((unsigned)C1->Kind < (unsigned)C2->Kind)
438 return true;
439 else if (C1->Kind == C2->Kind)
440 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
441 }
442 }
443 return false;
444 }
445 };
446
447}
448
449char IfConverter::ID = 0;
450
452
457
458bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
459 if (skipFunction(MF.getFunction()) || (PredicateFtor && !PredicateFtor(MF)))
460 return false;
461
463 TLI = ST.getTargetLowering();
464 TII = ST.getInstrInfo();
465 TRI = ST.getRegisterInfo();
467 getAnalysis().getMBFI());
468 MBPI = &getAnalysis().getMBPI();
470 &getAnalysis().getPSI();
471 MRI = &MF.getRegInfo();
472 SchedModel.init(&ST);
473
474 if () return false;
475
476 PreRegAlloc = MRI->isSSA();
477
478 bool BFChange = false;
479 if (!PreRegAlloc) {
480
481 BranchFolder BF(true, false, MBFI, *MBPI, PSI);
483 }
484
485 LLVM_DEBUG(dbgs() << "\nIfcvt: function (" << ++FnNum << ") \'"
486 << MF.getName() << "\'");
487
490 return false;
491 }
493
494 MF.RenumberBlocks();
495 BBAnalysis.resize(MF.getNumBlockIDs());
496
497 std::vector<std::unique_ptr> Tokens;
498 MadeChange = false;
499 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
500 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
502
503
504 bool Change = false;
505 AnalyzeBlocks(MF, Tokens);
506 while (!Tokens.empty()) {
507 std::unique_ptr Token = std::move(Tokens.back());
508 Tokens.pop_back();
509 BBInfo &BBI = Token->BBI;
510 IfcvtKind Kind = Token->Kind;
511 unsigned NumDups = Token->NumDups;
512 unsigned NumDups2 = Token->NumDups2;
513
514
515
516 if (BBI.IsDone)
517 BBI.IsEnqueued = false;
518 if (!BBI.IsEnqueued)
519 continue;
520
521 BBI.IsEnqueued = false;
522
523 bool RetVal = false;
524 switch (Kind) {
526 case ICSimple:
527 case ICSimpleFalse: {
528 bool isFalse = Kind == ICSimpleFalse;
531 << (Kind == ICSimpleFalse ? " false" : "")
533 << ((Kind == ICSimpleFalse) ? BBI.FalseBB->getNumber()
534 : BBI.TrueBB->getNumber())
535 << ") ");
536 RetVal = IfConvertSimple(BBI, Kind);
537 LLVM_DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
538 if (RetVal) {
539 if (isFalse) ++NumSimpleFalse;
540 else ++NumSimple;
541 }
542 break;
543 }
544 case ICTriangle:
545 case ICTriangleRev:
546 case ICTriangleFalse:
547 case ICTriangleFRev: {
548 bool isFalse = Kind == ICTriangleFalse;
549 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
554 if (isFalse)
556 if (isRev)
559 << " (T:" << BBI.TrueBB->getNumber()
560 << ",F:" << BBI.FalseBB->getNumber() << ") ");
561 RetVal = IfConvertTriangle(BBI, Kind);
562 LLVM_DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
563 if (RetVal) {
564 if (isFalse)
565 ++NumTriangleFalse;
566 else if (isRev)
567 ++NumTriangleRev;
568 else
569 ++NumTriangle;
570 }
571 break;
572 }
573 case ICDiamond:
576 << " (T:" << BBI.TrueBB->getNumber()
577 << ",F:" << BBI.FalseBB->getNumber() << ") ");
578 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
579 Token->TClobbersPred,
580 Token->FClobbersPred);
581 LLVM_DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
582 if (RetVal) ++NumDiamonds;
583 break;
584 case ICForkedDiamond:
588 << " (T:" << BBI.TrueBB->getNumber()
589 << ",F:" << BBI.FalseBB->getNumber() << ") ");
590 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
591 Token->TClobbersPred,
592 Token->FClobbersPred);
593 LLVM_DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
594 if (RetVal) ++NumForkedDiamonds;
595 break;
596 }
597
598 if (RetVal && MRI->tracksLiveness())
600
601 Change |= RetVal;
602
603 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
604 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
606 break;
607 }
608
609 if (!Change)
610 break;
611 MadeChange |= Change;
612 }
613
614 Tokens.clear();
615 BBAnalysis.clear();
616
618 BranchFolder BF(false, false, MBFI, *MBPI, PSI);
620 }
621
622 MadeChange |= BFChange;
623 return MadeChange;
624}
625
626
630 if (SuccBB != TrueBB)
631 return SuccBB;
632 }
633 return nullptr;
634}
635
636
637
638bool IfConverter::reverseBranchCondition(BBInfo &BBI) const {
639 DebugLoc dl;
642 TII->insertBranch(*BBI.BB, BBI.FalseBB, BBI.TrueBB, BBI.BrCond, dl);
643 std::swap(BBI.TrueBB, BBI.FalseBB);
644 return true;
645 }
646 return false;
647}
648
649
650
655 return nullptr;
656 return &*I;
657}
658
659
660
661
662bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups,
663 BranchProbability Prediction) const {
664 Dups = 0;
665 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
666 return false;
667
668 if (TrueBBI.IsBrAnalyzable)
669 return false;
670
671 if (TrueBBI.BB->pred_size() > 1) {
672 if (TrueBBI.CannotBeCopied ||
674 Prediction))
675 return false;
676 Dups = TrueBBI.NonPredSize;
677 }
678
679 return true;
680}
681
682
683
684
685
686
687bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
688 bool FalseBranch, unsigned &Dups,
689 BranchProbability Prediction) const {
690 Dups = 0;
691 if (TrueBBI.BB == FalseBBI.BB)
692 return false;
693
694 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
695 return false;
696
697 if (TrueBBI.BB->pred_size() > 1) {
698 if (TrueBBI.CannotBeCopied)
699 return false;
700
701 unsigned Size = TrueBBI.NonPredSize;
702 if (TrueBBI.IsBrAnalyzable) {
703 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
704
706 else {
707 MachineBasicBlock *FExit = FalseBranch
708 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
709 if (FExit)
710
712 }
713 }
715 return false;
717 }
718
719 MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB;
720 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
722 if (++I == TrueBBI.BB->getParent()->end())
723 return false;
724 TExit = &*I;
725 }
726 return TExit && TExit == FalseBBI.BB;
727}
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749bool IfConverter::CountDuplicatedInstructions(
754 unsigned &Dups1, unsigned &Dups2,
755 MachineBasicBlock &TBB, MachineBasicBlock &FBB,
756 bool SkipUnconditionalBranches) const {
757 while (TIB != TIE && FIB != FIE) {
758
761 if (TIB == TIE || FIB == FIE)
762 break;
763 if (!TIB->isIdenticalTo(*FIB))
764 break;
765
766
767 std::vector PredDefs;
769 return false;
770
771 if (!TIB->isBranch())
772 ++Dups1;
773 ++TIB;
774 ++FIB;
775 }
776
777
778 if (TIB == TIE || FIB == FIE)
779 return true;
780
781
782
783
788
790 if (SkipUnconditionalBranches) {
791 while (RTIE != RTIB && RTIE->isUnconditionalBranch())
792 ++RTIE;
793 while (RFIE != RFIB && RFIE->isUnconditionalBranch())
794 ++RFIE;
795 }
796 }
797
798
799 while (RTIE != RTIB && RFIE != RFIB) {
800
801
804 if (RTIE == RTIB || RFIE == RFIB)
805 break;
806 if (!RTIE->isIdenticalTo(*RFIE))
807 break;
808
809
810 if (!RTIE->isBranch())
811 ++Dups2;
812 ++RTIE;
813 ++RFIE;
814 }
817 return true;
818}
819
820
821
822
823
824
825
826
827
828
829bool IfConverter::RescanInstructions(
832 BBInfo &TrueBBI, BBInfo &FalseBBI) const {
833 bool BranchUnpredicable = true;
834 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable = false;
835 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
836 if (TrueBBI.IsUnpredicable)
837 return false;
838 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
839 if (FalseBBI.IsUnpredicable)
840 return false;
841 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
842 return false;
843 return true;
844}
845
846#ifndef NDEBUG
854 while (E1 != B1 && E2 != B2) {
857 if (E1 == B1 && E2 == B2)
858 break;
859
860 if (E1 == B1) {
861 assert(!E2->isBranch() && "Branch mis-match, one block is empty.");
862 break;
863 }
864 if (E2 == B2) {
865 assert(!E1->isBranch() && "Branch mis-match, one block is empty.");
866 break;
867 }
868
869 if (E1->isBranch() || E2->isBranch())
870 assert(E1->isIdenticalTo(*E2) &&
871 "Branch mis-match, branch instructions don't match.");
872 else
873 break;
874 ++E1;
875 ++E2;
876 }
877}
878#endif
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893bool IfConverter::ValidForkedDiamond(
894 BBInfo &TrueBBI, BBInfo &FalseBBI,
895 unsigned &Dups1, unsigned &Dups2,
896 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const {
897 Dups1 = Dups2 = 0;
898 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
899 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
900 return false;
901
902 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
903 return false;
904
905 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
906 return false;
907
908
909
910 if (TrueBBI.BrCond.size() == 0 ||
911 FalseBBI.BrCond.size() == 0)
912 return false;
913
914 MachineBasicBlock *TT = TrueBBI.TrueBB;
915 MachineBasicBlock *TF = TrueBBI.FalseBB;
916 MachineBasicBlock *FT = FalseBBI.TrueBB;
917 MachineBasicBlock *FF = FalseBBI.FalseBB;
918
919 if (!TT)
921 if (!TF)
923 if (!FT)
925 if (!FF)
927
928 if (!TT || !TF)
929 return false;
930
931
932 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
933 return false;
934
935 bool FalseReversed = false;
936 if (TF == FT && TT == FF) {
937
938 if (!FalseBBI.IsBrReversible)
939 return false;
940 FalseReversed = true;
941 reverseBranchCondition(FalseBBI);
942 }
944 if (FalseReversed)
945 reverseBranchCondition(FalseBBI);
946 });
947
948
953 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
954 *TrueBBI.BB, *FalseBBI.BB,
955 true))
956 return false;
957
958 TrueBBICalc.BB = TrueBBI.BB;
959 FalseBBICalc.BB = FalseBBI.BB;
960 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
961 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
962 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
963 return false;
964
965
966
967
968 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
969 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
970 return true;
971}
972
973
974
975bool IfConverter::ValidDiamond(
976 BBInfo &TrueBBI, BBInfo &FalseBBI,
977 unsigned &Dups1, unsigned &Dups2,
978 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const {
979 Dups1 = Dups2 = 0;
980 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
981 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
982 return false;
983
984
985
986 if (TrueBBI.BB == FalseBBI.BB)
987 return false;
988
989 MachineBasicBlock *TT = TrueBBI.TrueBB;
990 MachineBasicBlock *FT = FalseBBI.TrueBB;
991
992 if (!TT && blockAlwaysFallThrough(TrueBBI))
994 if (!FT && blockAlwaysFallThrough(FalseBBI))
996 if (TT != FT)
997 return false;
998 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
999 return false;
1000 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
1001 return false;
1002
1003
1004 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
1005 return false;
1006
1007
1008
1009
1010
1011 bool SkipUnconditionalBranches =
1012 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
1017 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
1018 *TrueBBI.BB, *FalseBBI.BB,
1019 SkipUnconditionalBranches))
1020 return false;
1021
1022 TrueBBICalc.BB = TrueBBI.BB;
1023 FalseBBICalc.BB = FalseBBI.BB;
1024 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
1025 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
1026 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
1027 return false;
1028
1029
1030
1031 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
1032 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
1033 return true;
1034}
1035
1036
1037
1038void IfConverter::AnalyzeBranches(BBInfo &BBI) {
1039 if (BBI.IsDone)
1040 return;
1041
1042 BBI.TrueBB = BBI.FalseBB = nullptr;
1043 BBI.BrCond.clear();
1044 BBI.IsBrAnalyzable =
1045 ->analyzeBranch(*BBI.BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond);
1046 if (!BBI.IsBrAnalyzable) {
1047 BBI.TrueBB = nullptr;
1048 BBI.FalseBB = nullptr;
1049 BBI.BrCond.clear();
1050 }
1051
1053 BBI.IsBrReversible = (RevCond.size() == 0) ||
1055 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB == nullptr;
1056
1057 if (BBI.BrCond.size()) {
1058
1059
1060 if (!BBI.FalseBB)
1062 if (!BBI.FalseBB) {
1063
1064 BBI.IsUnpredicable = true;
1065 }
1066 }
1067}
1068
1069
1070
1071
1072
1073
1074void IfConverter::ScanInstructions(BBInfo &BBI,
1077 bool BranchUnpredicable) const {
1078 if (BBI.IsDone || BBI.IsUnpredicable)
1079 return;
1080
1081 bool AlreadyPredicated = !BBI.Predicate.empty();
1082
1083 BBI.NonPredSize = 0;
1084 BBI.ExtraCost = 0;
1085 BBI.ExtraCost2 = 0;
1086 BBI.ClobbersPred = false;
1087 for (MachineInstr &MI : make_range(Begin, End)) {
1088 if (MI.isDebugInstr())
1089 continue;
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 if (MI.isNotDuplicable() || MI.isConvergent())
1122 BBI.CannotBeCopied = true;
1123
1125 bool isCondBr = BBI.IsBrAnalyzable && MI.isConditionalBranch();
1126
1127 if (BranchUnpredicable && MI.isBranch()) {
1128 BBI.IsUnpredicable = true;
1129 return;
1130 }
1131
1132
1133 if (isCondBr)
1134 continue;
1135
1136 if (!isPredicated) {
1137 BBI.NonPredSize++;
1139 unsigned NumCycles = SchedModel.computeInstrLatency(&MI, false);
1140 if (NumCycles > 1)
1141 BBI.ExtraCost += NumCycles-1;
1142 BBI.ExtraCost2 += ExtraPredCost;
1143 } else if (!AlreadyPredicated) {
1144
1145
1146
1147 BBI.IsUnpredicable = true;
1148 return;
1149 }
1150
1151 if (BBI.ClobbersPred && !isPredicated) {
1152
1153
1154
1155
1156 BBI.IsUnpredicable = true;
1157 return;
1158 }
1159
1160
1161
1162 std::vector PredDefs;
1164 BBI.ClobbersPred = true;
1165
1167 BBI.IsUnpredicable = true;
1168 return;
1169 }
1170 }
1171}
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
1183 SmallVectorImpl &Pred,
1184 bool isTriangle, bool RevBranch,
1185 bool hasCommonTail) {
1186
1187
1188
1189
1190 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1191 return false;
1192
1193
1194
1195
1196 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1197 return false;
1198
1199
1200
1202 return false;
1203
1204 if (!hasCommonTail && BBI.BrCond.size()) {
1205 if (!isTriangle)
1206 return false;
1207
1208
1211 if (RevBranch) {
1213 return false;
1214 }
1217 return false;
1218 }
1219
1220 return true;
1221}
1222
1223
1224
1225void IfConverter::AnalyzeBlock(
1226 MachineBasicBlock &MBB, std::vector<std::unique_ptr> &Tokens) {
1227 struct BBState {
1228 BBState(MachineBasicBlock &MBB) : MBB(&MBB) {}
1229 MachineBasicBlock *MBB;
1230
1231
1232 bool SuccsAnalyzed = false;
1233 };
1234
1235
1237
1238 while (!BBStack.empty()) {
1239 BBState &State = BBStack.back();
1240 MachineBasicBlock *BB = State.MBB;
1241 BBInfo &BBI = BBAnalysis[BB->getNumber()];
1242
1243 if (!State.SuccsAnalyzed) {
1244 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1245 BBStack.pop_back();
1246 continue;
1247 }
1248
1249 BBI.BB = BB;
1250 BBI.IsBeingAnalyzed = true;
1251
1252 AnalyzeBranches(BBI);
1255 ScanInstructions(BBI, Begin, End);
1256
1257
1258
1259 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1260 BBI.IsBeingAnalyzed = false;
1261 BBI.IsAnalyzed = true;
1262 BBStack.pop_back();
1263 continue;
1264 }
1265
1266
1267 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1268 BBI.IsBeingAnalyzed = false;
1269 BBI.IsAnalyzed = true;
1270 BBStack.pop_back();
1271 continue;
1272 }
1273
1274
1275 if (!BBI.FalseBB) {
1276 BBI.IsBeingAnalyzed = false;
1277 BBI.IsAnalyzed = true;
1278 BBStack.pop_back();
1279 continue;
1280 }
1281
1282
1283 State.SuccsAnalyzed = true;
1284 BBStack.push_back(*BBI.FalseBB);
1285 BBStack.push_back(*BBI.TrueBB);
1286 continue;
1287 }
1288
1289 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1290 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1291
1292 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1293 BBI.IsBeingAnalyzed = false;
1294 BBI.IsAnalyzed = true;
1295 BBStack.pop_back();
1296 continue;
1297 }
1298
1300 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1302
1303 unsigned Dups = 0;
1304 unsigned Dups2 = 0;
1305 bool TNeedSub = !TrueBBI.Predicate.empty();
1306 bool FNeedSub = !FalseBBI.Predicate.empty();
1307 bool Enqueued = false;
1308
1309 BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);
1310
1311 if (CanRevCond) {
1312 BBInfo TrueBBICalc, FalseBBICalc;
1313 auto feasibleDiamond = [&](bool Forked) {
1314 bool MeetsSize = MeetIfcvtSizeLimit(TrueBBICalc, FalseBBICalc, *BB,
1315 Dups + Dups2, Prediction, Forked);
1316 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1317 false, false,
1318 true);
1319 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1320 false, false,
1321 true);
1322 return MeetsSize && TrueFeasible && FalseFeasible;
1323 };
1324
1325 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1326 TrueBBICalc, FalseBBICalc)) {
1327 if (feasibleDiamond(false)) {
1328
1329
1330
1331
1332
1333
1334
1335
1336 Tokens.push_back(std::make_unique(
1337 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1338 (bool) TrueBBICalc.ClobbersPred, (bool) FalseBBICalc.ClobbersPred));
1339 Enqueued = true;
1340 }
1341 } else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1342 TrueBBICalc, FalseBBICalc)) {
1343 if (feasibleDiamond(true)) {
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354 Tokens.push_back(std::make_unique(
1355 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1356 (bool) TrueBBICalc.ClobbersPred, (bool) FalseBBICalc.ClobbersPred));
1357 Enqueued = true;
1358 }
1359 }
1360 }
1361
1362 if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&
1363 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1364 TrueBBI.ExtraCost2, Prediction) &&
1365 FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
1366
1367
1368
1369
1370
1371
1372
1373 Tokens.push_back(
1374 std::make_unique(BBI, ICTriangle, TNeedSub, Dups));
1375 Enqueued = true;
1376 }
1377
1378 if (ValidTriangle(TrueBBI, FalseBBI, true, Dups, Prediction) &&
1379 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1380 TrueBBI.ExtraCost2, Prediction) &&
1381 FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
1382 Tokens.push_back(
1383 std::make_unique(BBI, ICTriangleRev, TNeedSub, Dups));
1384 Enqueued = true;
1385 }
1386
1387 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1388 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1389 TrueBBI.ExtraCost2, Prediction) &&
1390 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1391
1392
1393
1394
1395
1396
1397
1398 Tokens.push_back(
1399 std::make_unique(BBI, ICSimple, TNeedSub, Dups));
1400 Enqueued = true;
1401 }
1402
1403 if (CanRevCond) {
1404
1405 if (ValidTriangle(FalseBBI, TrueBBI, false, Dups,
1407 MeetIfcvtSizeLimit(*FalseBBI.BB,
1408 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1409 FalseBBI.ExtraCost2, Prediction.getCompl()) &&
1410 FeasibilityAnalysis(FalseBBI, RevCond, true)) {
1411 Tokens.push_back(std::make_unique(BBI, ICTriangleFalse,
1412 FNeedSub, Dups));
1413 Enqueued = true;
1414 }
1415
1416 if (ValidTriangle(FalseBBI, TrueBBI, true, Dups,
1418 MeetIfcvtSizeLimit(*FalseBBI.BB,
1419 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1420 FalseBBI.ExtraCost2, Prediction.getCompl()) &&
1421 FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
1422 Tokens.push_back(
1423 std::make_unique(BBI, ICTriangleFRev, FNeedSub, Dups));
1424 Enqueued = true;
1425 }
1426
1427 if (ValidSimple(FalseBBI, Dups, Prediction.getCompl()) &&
1428 MeetIfcvtSizeLimit(*FalseBBI.BB,
1429 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1430 FalseBBI.ExtraCost2, Prediction.getCompl()) &&
1431 FeasibilityAnalysis(FalseBBI, RevCond)) {
1432 Tokens.push_back(
1433 std::make_unique(BBI, ICSimpleFalse, FNeedSub, Dups));
1434 Enqueued = true;
1435 }
1436 }
1437
1438 BBI.IsEnqueued = Enqueued;
1439 BBI.IsBeingAnalyzed = false;
1440 BBI.IsAnalyzed = true;
1441 BBStack.pop_back();
1442 }
1443}
1444
1445
1446void IfConverter::AnalyzeBlocks(
1447 MachineFunction &MF, std::vector<std::unique_ptr> &Tokens) {
1448 for (MachineBasicBlock &MBB : MF)
1449 AnalyzeBlock(MBB, Tokens);
1450
1451
1453}
1454
1455
1456
1462 while (I != TI) {
1463
1464
1465 if (I == E || ->empty() || !PI->isSuccessor(&*I))
1466 return false;
1467 PI = I++;
1468 }
1469
1470 return PI->isSuccessor(&*I);
1471}
1472
1473
1474
1475void IfConverter::InvalidatePreds(MachineBasicBlock &MBB) {
1476 for (const MachineBasicBlock *Predecessor : MBB.predecessors()) {
1477 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1478 if (PBBI.IsDone || PBBI.BB == &MBB)
1479 continue;
1480 PBBI.IsAnalyzed = false;
1481 PBBI.IsEnqueued = false;
1482 }
1483}
1484
1485
1488 DebugLoc dl;
1490 TII->insertBranch(MBB, &ToMBB, nullptr, NoCond, dl);
1491}
1492
1493
1494
1497
1498
1499
1500
1503 for (unsigned Reg : Redefs)
1505
1508
1509
1510 for (auto Clobber : Clobbers) {
1511
1512
1513 unsigned Reg = Clobber.first;
1517 if (Op.isRegMask()) {
1518
1519
1520 if (LiveBeforeMI.count(Reg))
1522
1523
1524
1525
1526
1527
1529 continue;
1530 }
1532 [&](MCPhysReg S) { return LiveBeforeMI.count(S); }))
1534 }
1535}
1536
1537
1538bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
1539 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1540 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1541 BBInfo *CvtBBI = &TrueBBI;
1542 BBInfo *NextBBI = &FalseBBI;
1543
1545 if (Kind == ICSimpleFalse)
1547
1548 MachineBasicBlock &CvtMBB = *CvtBBI->BB;
1549 MachineBasicBlock &NextMBB = *NextBBI->BB;
1550 if (CvtBBI->IsDone ||
1551 (CvtBBI->CannotBeCopied && CvtMBB.pred_size() > 1)) {
1552
1553 BBI.IsAnalyzed = false;
1554 CvtBBI->IsAnalyzed = false;
1555 return false;
1556 }
1557
1559
1560 return false;
1561
1562 if (Kind == ICSimpleFalse)
1565
1567
1568 if (MRI->tracksLiveness()) {
1569
1570
1573 }
1574
1575
1576
1578
1580
1581
1582 CopyAndPredicateBlock(BBI, *CvtBBI, Cond);
1583
1584
1585 BBI.BB->removeSuccessor(&CvtMBB, true);
1586 } else {
1587
1588 PredicateBlock(*CvtBBI, CvtMBB.end(), Cond);
1589
1590
1591
1592 MergeBlocks(BBI, *CvtBBI);
1593 }
1594
1595 bool IterIfcvt = true;
1598 BBI.HasFallThrough = false;
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609 IterIfcvt = false;
1610 }
1611
1612
1613 if (!IterIfcvt)
1614 BBI.IsDone = true;
1615 InvalidatePreds(*BBI.BB);
1616 CvtBBI->IsDone = true;
1617
1618
1619 return true;
1620}
1621
1622
1623bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1624 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1625 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1626 BBInfo *CvtBBI = &TrueBBI;
1627 BBInfo *NextBBI = &FalseBBI;
1628 DebugLoc dl;
1629
1631 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1633
1634 MachineBasicBlock &CvtMBB = *CvtBBI->BB;
1635 MachineBasicBlock &NextMBB = *NextBBI->BB;
1636 if (CvtBBI->IsDone ||
1637 (CvtBBI->CannotBeCopied && CvtMBB.pred_size() > 1)) {
1638
1639 BBI.IsAnalyzed = false;
1640 CvtBBI->IsAnalyzed = false;
1641 return false;
1642 }
1643
1645
1646 return false;
1647
1648 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1651
1652 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1653 if (reverseBranchCondition(*CvtBBI)) {
1654
1655
1656 for (MachineBasicBlock *PBB : CvtMBB.predecessors()) {
1657 if (PBB == BBI.BB)
1658 continue;
1659 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1660 if (PBBI.IsEnqueued) {
1661 PBBI.IsAnalyzed = false;
1662 PBBI.IsEnqueued = false;
1663 }
1664 }
1665 }
1666 }
1667
1668
1669
1671 if (MRI->tracksLiveness()) {
1674 }
1675
1676 bool HasEarlyExit = CvtBBI->FalseBB != nullptr;
1677 BranchProbability CvtNext, CvtFalse, BBNext, BBCvt;
1678
1679 if (HasEarlyExit) {
1680
1685 }
1686
1687
1688
1690
1692
1693
1694 CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true);
1695 } else {
1696
1698 PredicateBlock(*CvtBBI, CvtMBB.end(), Cond);
1699
1700
1701 MergeBlocks(BBI, *CvtBBI, false);
1702 }
1703
1704
1705 BBI.BB->removeSuccessor(&CvtMBB, true);
1706
1707
1708 if (HasEarlyExit) {
1710 CvtBBI->BrCond.end());
1713
1714
1715
1716
1717
1718
1719
1721 auto NewNext = BBNext + BBCvt * CvtNext;
1722 auto NewTrueBBIter = find(BBI.BB->successors(), NewTrueBB);
1723 if (NewTrueBBIter != BBI.BB->succ_end())
1724 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1725
1726 auto NewFalse = BBCvt * CvtFalse;
1727 TII->insertBranch(*BBI.BB, CvtBBI->FalseBB, nullptr, RevCond, dl);
1728 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1729 }
1730
1731
1732
1733 bool FalseBBDead = false;
1734 bool IterIfcvt = true;
1736 if (!isFallThrough) {
1737
1738
1739
1740 if (!HasEarlyExit && NextMBB.pred_size() == 1 &&
1741 blockNeverFallThrough(*NextBBI) && !NextMBB.hasAddressTaken()) {
1742 MergeBlocks(BBI, *NextBBI);
1743 FalseBBDead = true;
1744 } else {
1746 BBI.HasFallThrough = false;
1747 }
1748
1749
1750 IterIfcvt = false;
1751 }
1752
1753
1754 if (!IterIfcvt)
1755 BBI.IsDone = true;
1756 InvalidatePreds(*BBI.BB);
1757 CvtBBI->IsDone = true;
1758 if (FalseBBDead)
1759 NextBBI->IsDone = true;
1760
1761
1762 return true;
1763}
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776bool IfConverter::IfConvertDiamondCommon(
1777 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
1778 unsigned NumDups1, unsigned NumDups2,
1779 bool TClobbersPred, bool FClobbersPred,
1780 bool RemoveBranch, bool MergeAddEdges) {
1781
1782 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1783 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1784
1785 BBI.IsAnalyzed = false;
1786 TrueBBI.IsAnalyzed = false;
1787 FalseBBI.IsAnalyzed = false;
1788 return false;
1789 }
1790
1791 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1792
1793 return false;
1794
1795
1796
1797
1798 BBInfo *BBI1 = &TrueBBI;
1799 BBInfo *BBI2 = &FalseBBI;
1805
1806
1807 bool DoSwap = false;
1808 if (TClobbersPred && !FClobbersPred)
1809 DoSwap = true;
1810 else if (!TClobbersPred && !FClobbersPred) {
1811 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1812 DoSwap = true;
1813 } else if (TClobbersPred && FClobbersPred)
1814 llvm_unreachable("Predicate info cannot be clobbered by both sides.");
1815 if (DoSwap) {
1818 }
1819
1820
1822
1823 MachineBasicBlock &MBB1 = *BBI1->BB;
1824 MachineBasicBlock &MBB2 = *BBI2->BB;
1825
1826
1827
1828
1829
1830
1831
1833 if (MRI->tracksLiveness()) {
1836 }
1837
1838
1839
1842 BBI1->NonPredSize -= NumDups1;
1843 BBI2->NonPredSize -= NumDups1;
1844
1845
1846
1847
1848 for (unsigned i = 0; i < NumDups1; ++DI1) {
1849 if (DI1 == MBB1.end())
1850 break;
1851 if (!DI1->isDebugInstr())
1852 ++i;
1853 }
1854 while (NumDups1 != 0) {
1855
1856
1857 if (DI2->shouldUpdateAdditionalCallInfo())
1859
1860 ++DI2;
1861 if (DI2 == MBB2.end())
1862 break;
1863 if (!DI2->isDebugInstr())
1864 --NumDups1;
1865 }
1866
1867 if (MRI->tracksLiveness()) {
1871 }
1872 }
1873
1874 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.begin(), DI1);
1876
1877
1878
1879
1880
1881
1882
1883#ifndef NDEBUG
1884
1885 if (!BBI1->IsBrAnalyzable)
1887#endif
1888
1889
1890 DI1 = MBB1.end();
1891 while (DI1 != MBB1.begin()) {
1893 if (!Prev->isBranch() && !Prev->isDebugInstr())
1894 break;
1895 DI1 = Prev;
1896 }
1897 for (unsigned i = 0; i != NumDups2; ) {
1898
1899
1901
1902 --DI1;
1903
1904
1905
1906 if (DI1->shouldUpdateAdditionalCallInfo())
1908
1909
1910 if (!DI1->isDebugInstr())
1911 ++i;
1912 }
1913 MBB1.erase(DI1, MBB1.end());
1914
1915 DI2 = BBI2->BB->end();
1916
1917
1918 if (RemoveBranch)
1920 else {
1921
1922
1923 while (DI2 != MBB2.begin()) {
1925 if (!Prev->isBranch() && !Prev->isDebugInstr())
1926 break;
1927 DI2 = Prev;
1928 }
1929 }
1930 while (NumDups2 != 0) {
1931
1932
1934 --DI2;
1935
1936 if (!DI2->isDebugInstr())
1937 --NumDups2;
1938 }
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948 SmallSet<MCRegister, 4> RedefsByFalse;
1949 SmallSet<MCRegister, 4> ExtUses;
1951 for (const MachineInstr &FI : make_range(MBB2.begin(), DI2)) {
1952 if (FI.isDebugInstr())
1953 continue;
1955 for (const MachineOperand &MO : FI.operands()) {
1956 if (!MO.isReg())
1957 continue;
1959 if ()
1960 continue;
1961 if (MO.isDef()) {
1963 } else if (!RedefsByFalse.count(Reg)) {
1964
1965
1967 }
1968 }
1969
1970 for (MCRegister Reg : Defs) {
1973 }
1974 }
1975 }
1976
1977
1978 PredicateBlock(*BBI1, MBB1.end(), *Cond1, &RedefsByFalse);
1979
1980
1981
1982
1983
1984
1985
1986
1987 if (!MBB2.empty() && (DI2 == MBB2.end())) {
1990 bool BB1Predicated = BBI1T != MBB1.end() && TII->isPredicated(*BBI1T);
1991 bool BB2NonPredicated = BBI2T != MBB2.end() && ->isPredicated(*BBI2T);
1992 if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable))
1993 --DI2;
1994 }
1995
1996
1997 PredicateBlock(*BBI2, DI2, *Cond2);
1998
1999
2000 MergeBlocks(BBI, *BBI1, MergeAddEdges);
2001 MergeBlocks(BBI, *BBI2, MergeAddEdges);
2002 return true;
2003}
2004
2005
2006
2007bool IfConverter::IfConvertForkedDiamond(
2008 BBInfo &BBI, IfcvtKind Kind,
2009 unsigned NumDups1, unsigned NumDups2,
2010 bool TClobbersPred, bool FClobbersPred) {
2011 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2012 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2013
2014
2017 if (TIE != TrueBBI.BB->end())
2018 dl = TIE->getDebugLoc();
2019
2020
2021
2022 if (!IfConvertDiamondCommon(
2023 BBI, TrueBBI, FalseBBI,
2024 NumDups1, NumDups2,
2025 TClobbersPred, FClobbersPred,
2026 true, true))
2027 return false;
2028
2029
2030
2031 TII->insertBranch(*BBI.BB, TrueBBI.TrueBB, TrueBBI.FalseBB,
2032 TrueBBI.BrCond, dl);
2033
2034
2035 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true;
2036 InvalidatePreds(*BBI.BB);
2037
2038
2039 return true;
2040}
2041
2042
2043bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
2044 unsigned NumDups1, unsigned NumDups2,
2045 bool TClobbersPred, bool FClobbersPred) {
2046 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2047 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2048 MachineBasicBlock *TailBB = TrueBBI.TrueBB;
2049
2050
2051 if (!TailBB) {
2052 if (blockAlwaysFallThrough(TrueBBI))
2053 TailBB = FalseBBI.TrueBB;
2054 assert((TailBB || !TrueBBI.IsBrAnalyzable) && "Unexpected!");
2055 }
2056
2057 if (!IfConvertDiamondCommon(
2058 BBI, TrueBBI, FalseBBI,
2059 NumDups1, NumDups2,
2060 TClobbersPred, FClobbersPred,
2061 TrueBBI.IsBrAnalyzable,
2062 TailBB == nullptr))
2063 return false;
2064
2065
2066
2067
2068
2069 if (TailBB) {
2070
2071
2072 BBI.BB->removeSuccessor(TrueBBI.BB);
2073 BBI.BB->removeSuccessor(FalseBBI.BB, true);
2074
2075 BBInfo &TailBBI = BBAnalysis[TailBB->getNumber()];
2076 bool CanMergeTail =
2077 blockNeverFallThrough(TailBBI) && !TailBBI.BB->hasAddressTaken();
2078
2079
2080
2083 CanMergeTail = false;
2084
2085
2086 unsigned NumPreds = TailBB->pred_size();
2087 if (NumPreds > 1)
2088 CanMergeTail = false;
2089 else if (NumPreds == 1 && CanMergeTail) {
2091 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2092 CanMergeTail = false;
2093 }
2094 if (CanMergeTail) {
2095 MergeBlocks(BBI, TailBBI);
2096 TailBBI.IsDone = true;
2097 } else {
2100 BBI.HasFallThrough = false;
2101 }
2102 }
2103
2104
2105 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true;
2106 InvalidatePreds(*BBI.BB);
2107
2108
2109 return true;
2110}
2111
2114 bool SawStore = true;
2115 if (.isSafeToMove(SawStore))
2116 return false;
2117
2119 if (!MO.isReg())
2120 continue;
2122 if ()
2123 continue;
2124 if (MO.isDef() && !LaterRedefs.count(Reg))
2125 return false;
2126 }
2127
2128 return true;
2129}
2130
2131
2132
2134 SmallVectorImpl &Cond,
2135 SmallSet<MCRegister, 4> *LaterRedefs) {
2136 bool AnyUnpred = false;
2137 bool MaySpec = LaterRedefs != nullptr;
2138 for (MachineInstr &I : make_range(BBI.BB->begin(), E)) {
2140 continue;
2141
2142
2143
2145 AnyUnpred = true;
2146 continue;
2147 }
2148
2149
2150 MaySpec = false;
2152#ifndef NDEBUG
2153 dbgs() << "Unable to predicate " << I << "!\n";
2154#endif
2156 }
2157
2158
2159
2161 }
2162
2163 BBI.Predicate.append(Cond.begin(), Cond.end());
2164
2165 BBI.IsAnalyzed = false;
2166 BBI.NonPredSize = 0;
2167
2168 ++NumIfConvBBs;
2169 if (AnyUnpred)
2170 ++NumUnpred;
2171}
2172
2173
2174
2175void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
2176 SmallVectorImpl &Cond,
2177 bool IgnoreBr) {
2178 MachineFunction &MF = *ToBBI.BB->getParent();
2179
2180 MachineBasicBlock &FromMBB = *FromBBI.BB;
2181 for (MachineInstr &I : FromMBB) {
2182
2183 if (IgnoreBr && I.isBranch())
2184 break;
2185
2186 MachineInstr *MI = MF.CloneMachineInstr(&I);
2187
2188 if (I.isCandidateForAdditionalCallInfo())
2190
2191 ToBBI.BB->insert(ToBBI.BB->end(), MI);
2192 ToBBI.NonPredSize++;
2194 unsigned NumCycles = SchedModel.computeInstrLatency(&I, false);
2195 if (NumCycles > 1)
2196 ToBBI.ExtraCost += NumCycles-1;
2197 ToBBI.ExtraCost2 += ExtraPredCost;
2198
2201#ifndef NDEBUG
2202 dbgs() << "Unable to predicate " << I << "!\n";
2203#endif
2205 }
2206 }
2207
2208
2209
2211 }
2212
2213 if (!IgnoreBr) {
2214 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2215 FromMBB.succ_end());
2216 MachineBasicBlock *NBB = getNextBlock(FromMBB);
2217 MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : nullptr;
2218
2219 for (MachineBasicBlock *Succ : Succs) {
2220
2221 if (Succ == FallThrough)
2222 continue;
2223 ToBBI.BB->addSuccessor(Succ);
2224 }
2225 }
2226
2227 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2228 ToBBI.Predicate.append(Cond.begin(), Cond.end());
2229
2230 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2231 ToBBI.IsAnalyzed = false;
2232
2233 ++NumDupBBs;
2234}
2235
2236
2237
2238
2239
2240
2241void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) {
2242 MachineBasicBlock &FromMBB = *FromBBI.BB;
2244 "Removing a BB whose address is taken!");
2245
2246
2247
2249 for (MachineInstr &MI : FromMBB)
2250 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2251 for (MachineOperand &MO : MI.operands())
2252 if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
2254
2255
2256
2259 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.begin(), FromTI);
2260
2261
2262 if (FromTI != FromMBB.end() && ->isPredicated(*FromTI))
2263 ToTI = ToBBI.BB->end();
2264 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.end());
2265
2266
2267
2268
2269
2270 if (ToBBI.IsBrAnalyzable)
2271 ToBBI.BB->normalizeSuccProbs();
2272
2273 SmallVector<MachineBasicBlock *, 4> FromSuccs(FromMBB.successors());
2274 MachineBasicBlock *NBB = getNextBlock(FromMBB);
2275 MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB : nullptr;
2276
2277
2279 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2280
2281
2283 ToBBI.BB->removeSuccessor(&FromMBB);
2284 }
2285
2286 for (MachineBasicBlock *Succ : FromSuccs) {
2287
2288 if (Succ == FallThrough) {
2289 FromMBB.removeSuccessor(Succ);
2290 continue;
2291 }
2292
2294 if (AddEdges) {
2295
2296
2297
2298
2300
2301
2302
2303
2304
2305
2306 if (!To2FromProb.isZero())
2307 NewProb *= To2FromProb;
2308 }
2309
2310 FromMBB.removeSuccessor(Succ);
2311
2312 if (AddEdges) {
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335 if (ToBBI.BB->isSuccessor(Succ))
2336 ToBBI.BB->setSuccProbability(
2337 find(ToBBI.BB->successors(), Succ),
2339 else
2340 ToBBI.BB->addSuccessor(Succ, NewProb);
2341 }
2342 }
2343
2344
2345
2346 MachineBasicBlock *Last = &*FromMBB.getParent()->rbegin();
2347 if (Last != &FromMBB)
2348 FromMBB.moveAfter(Last);
2349
2350
2351
2352 if (ToBBI.IsBrAnalyzable && FromBBI.IsBrAnalyzable)
2353 ToBBI.BB->normalizeSuccProbs();
2354
2355 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2356 FromBBI.Predicate.clear();
2357
2358 ToBBI.NonPredSize += FromBBI.NonPredSize;
2359 ToBBI.ExtraCost += FromBBI.ExtraCost;
2360 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2361 FromBBI.NonPredSize = 0;
2362 FromBBI.ExtraCost = 0;
2363 FromBBI.ExtraCost2 = 0;
2364
2365 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2366 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2367 ToBBI.IsAnalyzed = false;
2368 FromBBI.IsAnalyzed = false;
2369}
2370
2371FunctionPass *
2373 return new IfConverter(std::move(Ftor));
2374}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
Function Alias Analysis false
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
findFalseBlock - BB has a fallthrough.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< bool > DisableTriangle("disable-ifcvt-triangle", cl::init(false), cl::Hidden)
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
BB has a fallthrough. Find its 'false' successor given its 'true' successor.
Definition IfConversion.cpp:627
static cl::opt< int > IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden)
static cl::opt< bool > IfCvtBranchFold("ifcvt-branch-fold", cl::init(true), cl::Hidden)
static cl::opt< bool > DisableTriangleF("disable-ifcvt-triangle-false", cl::init(false), cl::Hidden)
static cl::opt< int > IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden)
static void InsertUncondBranch(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB, const TargetInstrInfo *TII)
Inserts an unconditional branch from MBB to ToMBB.
Definition IfConversion.cpp:1486
static void verifySameBranchInstructions(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2)
Definition IfConversion.cpp:847
static cl::opt< bool > DisableDiamond("disable-ifcvt-diamond", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableTriangleR("disable-ifcvt-triangle-rev", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableForkedDiamond("disable-ifcvt-forked-diamond", cl::init(false), cl::Hidden)
static MachineBasicBlock * getNextBlock(MachineBasicBlock &MBB)
Returns the next block in the function blocks ordering.
Definition IfConversion.cpp:651
static bool MaySpeculate(const MachineInstr &MI, SmallSet< MCRegister, 4 > &LaterRedefs)
Definition IfConversion.cpp:2112
static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs)
Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all values defined in MI whic...
Definition IfConversion.cpp:1495
static cl::opt< bool > DisableSimpleF("disable-ifcvt-simple-false", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableSimple("disable-ifcvt-simple", cl::init(false), cl::Hidden)
static bool canFallThroughTo(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB)
Returns true either if ToMBB is the next block after MBB or that all the intervening blocks are empty...
Definition IfConversion.cpp:1457
static cl::opt< int > IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden)
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
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)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallSet class.
This file defines the SmallVector 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)
This file describes how to lower LLVM code to machine code.
AnalysisUsage & addRequired()
bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, const TargetRegisterInfo *tri, MachineLoopInfo *mli=nullptr, bool AfterPlacement=false)
Perhaps branch folding, tail merging and other CFG optimizations on the given function.
static BranchProbability getOne()
BranchProbability getCompl() const
static BranchProbability getZero()
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
A set of physical registers with utility functions to track liveness when walking backward/forward th...
void stepForward(const MachineInstr &MI, SmallVectorImpl< std::pair< MCPhysReg, const MachineOperand * > > &Clobbers)
Simulates liveness when stepping forward over an instruction(bundle).
void init(const TargetRegisterInfo &TRI)
(re-)initializes and clears the set.
void addLiveInsNoPristines(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB but skips pristine registers.
unsigned pred_size() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool mayHaveInlineAsmBr() const
Returns true if this block may have an INLINEASM_BR (overestimate, by checking if any of the successo...
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) 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.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
void eraseAdditionalCallInfo(const MachineInstr *MI)
Following functions update call site info.
void copyAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Copy the call site info from Old to \ New.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
MachineOperand class - Representation of each machine instruction operand.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
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.
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
size_type count(const KeyT &Key) const
count - Returns 1 if this set contains an element identified by Key, 0 otherwise.
void setUniverse(unsigned U)
setUniverse - Set the universe size which determines the largest key the set can hold.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
Reverses the branch condition of the specified condition list, returning false on success and true if...
virtual unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const
Remove the branching code at the end of the specific MBB.
virtual bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const
If the specified instruction defines any predicate or condition code register(s) used for predication...
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
virtual bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const
Convert the instruction into a predicated instruction.
virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const
Return true if it's profitable to unpredicate one side of a 'diamond', i.e.
virtual bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const
Returns true if the first specified predicate subsumes the second, e.g.
virtual unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const
Insert branch code into the end of the specified MachineBasicBlock.
virtual bool isPredicated(const MachineInstr &MI) const
Returns true if the instruction is already predicated.
virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const
Return true if it's profitable for if-converter to duplicate instructions of specified accumulated in...
virtual unsigned getPredicationCost(const MachineInstr &MI) const
virtual bool isPredicable(const MachineInstr &MI) const
Return true if the specified instruction can be predicated.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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.
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI FunctionPass * createIfConverter(std::function< bool(const MachineFunction &)> Ftor)
Definition IfConversion.cpp:2372
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI char & IfConverterID
IfConverter - This pass performs machine code if conversion.
Definition IfConversion.cpp:451
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
LLVM_ABI void initializeIfConverterPass(PassRegistry &)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.