LLVM: lib/Target/Hexagon/HexagonHardwareLoops.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
54#include
55#include
56#include
57#include
58#include
59#include
60#include
61#include
62#include
63
64using namespace llvm;
65
66#define DEBUG_TYPE "hwloops"
67
68#ifndef NDEBUG
70
71
74#endif
75
76
79 cl::desc("Add a preheader to a hardware loop if one doesn't exist"));
80
81
82
83
85 cl::desc("Allow speculation of preheader "
86 "instructions"));
87
88STATISTIC(NumHWLoops, "Number of loops converted to hardware loops");
89
90namespace {
91
92 class CountValue;
93
100#ifndef NDEBUG
101 static int Counter;
102#endif
103
104 public:
105 static char ID;
106
108
109 bool runOnMachineFunction(MachineFunction &MF) override;
110
111 StringRef getPassName() const override { return "Hexagon Hardware Loops"; }
112
113 void getAnalysisUsage(AnalysisUsage &AU) const override {
114 AU.addRequired();
115 AU.addRequired();
117 }
118
119 private:
120 using LoopFeederMap = std::map<Register, MachineInstr *>;
121
122
123 struct Comparison {
124 enum Kind {
125 EQ = 0x01,
126 NE = 0x02,
127 L = 0x04,
128 G = 0x08,
129 U = 0x40,
130 LTs = L,
131 LEs = L | EQ,
132 GTs = G,
133 GEs = G | EQ,
134 LTu = L | U,
135 LEu = L | EQ | U,
136 GTu = G | U,
137 GEu = G | EQ | U
138 };
139
140 static Kind getSwappedComparison(Kind Cmp) {
141 assert ((!((Cmp & L) && (Cmp & G))) && "Malformed comparison operator");
142 if ((Cmp & L) || (Cmp & G))
143 return (Kind)(Cmp ^ (L|G));
144 return Cmp;
145 }
146
147 static Kind getNegatedComparison(Kind Cmp) {
148 if ((Cmp & L) || (Cmp & G))
149 return (Kind)((Cmp ^ (L | G)) ^ EQ);
150 if ((Cmp & NE) || (Cmp & EQ))
151 return (Kind)(Cmp ^ (EQ | NE));
152 return (Kind)0;
153 }
154
155 static bool isSigned(Kind Cmp) {
156 return (Cmp & (L | G) && !(Cmp & U));
157 }
158
159 static bool isUnsigned(Kind Cmp) {
160 return (Cmp & U);
161 }
162 };
163
164
165
166
167
168
169
170
171
172
173
174
175
176 bool findInductionRegister(MachineLoop *L, Register &Reg,
177 int64_t &IVBump, MachineInstr *&IVOp) const;
178
179
180 Comparison::Kind getComparisonKind(unsigned CondOpc,
181 MachineOperand *InitialValue,
182 const MachineOperand *Endvalue,
183 int64_t IVBump) const;
184
185
186
187
188 CountValue *getLoopTripCount(MachineLoop *L,
189 SmallVectorImpl<MachineInstr *> &OldInsts);
190
191
192
193
194
195
196
197
198 CountValue *computeCount(MachineLoop *Loop, const MachineOperand *Start,
199 const MachineOperand *End, Register IVReg,
200 int64_t IVBump, Comparison::Kind Cmp) const;
201
202
203
204 bool isInvalidLoopOperation(const MachineInstr *MI,
205 bool IsInnerHWLoop) const;
206
207
208
209 bool containsInvalidInstruction(MachineLoop *L, bool IsInnerHWLoop) const;
210
211
212
213 bool convertToHardwareLoop(MachineLoop *L, bool &L0used, bool &L1used);
214
215
216 bool isDead(const MachineInstr *MI,
217 SmallVectorImpl<MachineInstr *> &DeadPhis) const;
218
219
220 void removeIfDead(MachineInstr *MI);
221
222
223
224
225
226 bool orderBumpCompare(MachineInstr *BumpI, MachineInstr *CmpI);
227
228
229
230
231 bool isLoopFeeder(MachineLoop *L, MachineBasicBlock *A, MachineInstr *MI,
232 const MachineOperand *MO,
233 LoopFeederMap &LoopFeederPhi) const;
234
235
236
237 bool phiMayWrapOrUnderflow(MachineInstr *Phi, const MachineOperand *EndVal,
238 MachineBasicBlock *MBB, MachineLoop *L,
239 LoopFeederMap &LoopFeederPhi) const;
240
241
242
243 bool loopCountMayWrapOrUnderFlow(const MachineOperand *InitVal,
244 const MachineOperand *EndVal,
245 MachineBasicBlock *MBB, MachineLoop *L,
246 LoopFeederMap &LoopFeederPhi) const;
247
248
249
250
251 bool checkForImmediate(const MachineOperand &MO, int64_t &Val) const;
252
253
254 bool isImmediate(const MachineOperand &MO) const {
255 int64_t V;
256 return checkForImmediate(MO, V);
257 }
258
259
260 int64_t getImmediate(const MachineOperand &MO) const {
261 int64_t V;
262 if (!checkForImmediate(MO, V))
264 return V;
265 }
266
267
268
269
270 void setImmediate(MachineOperand &MO, int64_t Val);
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 bool fixupInductionVariable(MachineLoop *L);
292
293
294
295 MachineBasicBlock *createPreheaderForLoop(MachineLoop *L);
296 };
297
298 char HexagonHardwareLoops::ID = 0;
299#ifndef NDEBUG
300 int HexagonHardwareLoops::Counter = 0;
301#endif
302
303
304
305
306 class CountValue {
307 public:
308 enum CountValueType {
309 CV_Register,
310 CV_Immediate
311 };
312
313 private:
314 CountValueType Kind;
315 union Values {
316 Values() : R{Register(), 0} {}
317 Values(const Values&) = default;
318 struct {
320 unsigned Sub;
321 } R;
322 unsigned ImmVal;
323 } Contents;
324
325 public:
326 explicit CountValue(CountValueType t, Register v, unsigned u = 0) {
327 Kind = t;
328 if (Kind == CV_Register) {
329 Contents.R.Reg = v;
330 Contents.R.Sub = u;
331 } else {
332 Contents.ImmVal = v;
333 }
334 }
335
336 bool isReg() const { return Kind == CV_Register; }
337 bool isImm() const { return Kind == CV_Immediate; }
338
340 assert(isReg() && "Wrong CountValue accessor");
341 return Contents.R.Reg;
342 }
343
344 unsigned getSubReg() const {
345 assert(isReg() && "Wrong CountValue accessor");
346 return Contents.R.Sub;
347 }
348
349 unsigned getImm() const {
350 assert(isImm() && "Wrong CountValue accessor");
351 return Contents.ImmVal;
352 }
353
354 void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const {
355 if (isReg()) { OS << printReg(Contents.R.Reg, TRI, Contents.R.Sub); }
356 if (isImm()) { OS << Contents.ImmVal; }
357 }
358 };
359
360}
361
363 "Hexagon Hardware Loops", false, false)
368
370 return new HexagonHardwareLoops();
371}
372
373bool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) {
374 LLVM_DEBUG(dbgs() << "********* Hexagon Hardware Loops *********\n");
376 return false;
377
379
380 MLI = &getAnalysis().getLI();
382 MDT = &getAnalysis().getDomTree();
386
387 for (auto &L : *MLI)
388 if (L->isOutermost()) {
389 bool L0Used = false;
390 bool L1Used = false;
391 Changed |= convertToHardwareLoop(L, L0Used, L1Used);
392 }
393
395}
396
397bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L,
399 int64_t &IVBump,
400 MachineInstr *&IVOp
401 ) const {
402 MachineBasicBlock *Header = L->getHeader();
403 MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader);
404 MachineBasicBlock *Latch = L->getLoopLatch();
405 MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
406 if (!Header || !Preheader || !Latch || !ExitingBlock)
407 return false;
408
409
410
411 using RegisterBump = std::pair<Register, int64_t>;
412
413
414
415
416
417 using InductionMap = std::map<Register, RegisterBump>;
418
419 InductionMap IndMap;
420
422
423 for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
424 I != E && I->isPHI(); ++I) {
426
427
428
429
430 for (unsigned i = 1, n = Phi->getNumOperands(); i < n; i += 2) {
431 if (Phi->getOperand(i+1).getMBB() != Latch)
432 continue;
433
434 Register PhiOpReg = Phi->getOperand(i).getReg();
435 MachineInstr *DI = MRI->getVRegDef(PhiOpReg);
436
438
439
441 MachineOperand &Opnd2 = DI->getOperand(2);
442 int64_t V;
443 if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
445 IndMap.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
446 }
447 }
448 }
449 }
450
452 MachineBasicBlock *TB = nullptr, *FB = nullptr;
454 if (NotAnalyzed)
455 return false;
456
458 unsigned PredPos, PredRegFlags;
459 if (->getPredReg(Cond, PredR, PredPos, PredRegFlags))
460 return false;
461
462 MachineInstr *PredI = MRI->getVRegDef(PredR);
464 return false;
465
467 int64_t CmpImm = 0, CmpMask = 0;
468 bool CmpAnalyzed =
470
471
472
473 if (!CmpAnalyzed)
474 return false;
475
476
477
478 InductionMap::iterator IndMapEnd = IndMap.end();
479 InductionMap::iterator F = IndMapEnd;
480 if (CmpReg1 != 0) {
481 InductionMap::iterator F1 = IndMap.find(CmpReg1);
482 if (F1 != IndMapEnd)
483 F = F1;
484 }
485 if (CmpReg2 != 0) {
486 InductionMap::iterator F2 = IndMap.find(CmpReg2);
487 if (F2 != IndMapEnd) {
488 if (F != IndMapEnd)
489 return false;
490 F = F2;
491 }
492 }
493 if (F == IndMapEnd)
494 return false;
495
497 IVBump = F->second.second;
498 IVOp = MRI->getVRegDef(F->first);
499 return true;
500}
501
502
503HexagonHardwareLoops::Comparison::Kind
504HexagonHardwareLoops::getComparisonKind(unsigned CondOpc,
505 MachineOperand *InitialValue,
506 const MachineOperand *EndValue,
507 int64_t IVBump) const {
508 Comparison::Kind Cmp = (Comparison::Kind)0;
509 switch (CondOpc) {
510 case Hexagon::C2_cmpeq:
511 case Hexagon::C2_cmpeqi:
512 case Hexagon::C2_cmpeqp:
513 Cmp = Comparison::EQ;
514 break;
515 case Hexagon::C4_cmpneq:
516 case Hexagon::C4_cmpneqi:
517 Cmp = Comparison::NE;
518 break;
519 case Hexagon::C2_cmplt:
520 Cmp = Comparison::LTs;
521 break;
522 case Hexagon::C2_cmpltu:
523 Cmp = Comparison::LTu;
524 break;
525 case Hexagon::C4_cmplte:
526 case Hexagon::C4_cmpltei:
527 Cmp = Comparison::LEs;
528 break;
529 case Hexagon::C4_cmplteu:
530 case Hexagon::C4_cmplteui:
531 Cmp = Comparison::LEu;
532 break;
533 case Hexagon::C2_cmpgt:
534 case Hexagon::C2_cmpgti:
535 case Hexagon::C2_cmpgtp:
536 Cmp = Comparison::GTs;
537 break;
538 case Hexagon::C2_cmpgtu:
539 case Hexagon::C2_cmpgtui:
540 case Hexagon::C2_cmpgtup:
541 Cmp = Comparison::GTu;
542 break;
543 case Hexagon::C2_cmpgei:
544 Cmp = Comparison::GEs;
545 break;
546 case Hexagon::C2_cmpgeui:
547 Cmp = Comparison::GEs;
548 break;
549 default:
550 return (Comparison::Kind)0;
551 }
552 return Cmp;
553}
554
555
556
557
558
559
560
561
562CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
563 SmallVectorImpl<MachineInstr *> &OldInsts) {
564 MachineBasicBlock *TopMBB = L->getTopBlock();
567 "Loop must have more than one incoming edge!");
568 MachineBasicBlock *Backedge = *PI++;
569 if (PI == TopMBB->pred_end())
570 return nullptr;
571 MachineBasicBlock *Incoming = *PI++;
572 if (PI != TopMBB->pred_end())
573 return nullptr;
574
575
576
577 if (L->contains(Incoming)) {
578 if (L->contains(Backedge))
579 return nullptr;
581 } else if (->contains(Backedge))
582 return nullptr;
583
584
585
586
587 MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
588 if (!ExitingBlock)
589 return nullptr;
590
592 int64_t IVBump = 0;
593 MachineInstr *IVOp;
594 bool FoundIV = findInductionRegister(L, IVReg, IVBump, IVOp);
595 if (!FoundIV)
596 return nullptr;
597
598 MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader);
599
600 MachineOperand *InitialValue = nullptr;
601 MachineInstr *IV_Phi = MRI->getVRegDef(IVReg);
602 MachineBasicBlock *Latch = L->getLoopLatch();
603 for (unsigned i = 1, n = IV_Phi->getNumOperands(); i < n; i += 2) {
605 if (MBB == Preheader)
606 InitialValue = &IV_Phi->getOperand(i);
607 else if (MBB == Latch)
608 IVReg = IV_Phi->getOperand(i).getReg();
609 }
610 if (!InitialValue)
611 return nullptr;
612
614 MachineBasicBlock *TB = nullptr, *FB = nullptr;
616 if (NotAnalyzed)
617 return nullptr;
618
619 MachineBasicBlock *Header = L->getHeader();
620
621
622
623 assert (TB && "Exit block without a branch?");
624 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
625 MachineBasicBlock *LTB = nullptr, *LFB = nullptr;
627 bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false);
628 if (NotAnalyzed)
629 return nullptr;
630 if (TB == Latch)
631 TB = (LTB == Header) ? LTB : LFB;
632 else
633 FB = (LTB == Header) ? LTB: LFB;
634 }
635 assert ((!FB || TB == Header || FB == Header) && "Branches not to header?");
636 if (!TB || (FB && TB != Header && FB != Header))
637 return nullptr;
638
639
640
641
642
643 bool Negated = TII->predOpcodeHasNot(Cond) ^ (TB != Header);
645 unsigned PredPos, PredRegFlags;
646 if (->getPredReg(Cond, PredReg, PredPos, PredRegFlags))
647 return nullptr;
648 MachineInstr *CondI = MRI->getVRegDef(PredReg);
649 unsigned CondOpc = CondI->getOpcode();
650
652 int64_t Mask = 0, ImmValue = 0;
653 bool AnalyzedCmp =
655 if (!AnalyzedCmp)
656 return nullptr;
657
658
659
662
663
664
665
666
667
668 Comparison::Kind Cmp;
669 bool isSwapped = false;
670 const MachineOperand &Op1 = CondI->getOperand(1);
671 const MachineOperand &Op2 = CondI->getOperand(2);
672 const MachineOperand *EndValue = nullptr;
673
674 if (Op1.isReg()) {
675 if (Op2.isImm() || Op1.getReg() == IVReg)
676 EndValue = &Op2;
677 else {
678 EndValue = &Op1;
679 isSwapped = true;
680 }
681 }
682
683 if (!EndValue)
684 return nullptr;
685
686 Cmp = getComparisonKind(CondOpc, InitialValue, EndValue, IVBump);
687 if (!Cmp)
688 return nullptr;
689 if (Negated)
690 Cmp = Comparison::getNegatedComparison(Cmp);
691 if (isSwapped)
692 Cmp = Comparison::getSwappedComparison(Cmp);
693
694 if (InitialValue->isReg()) {
696 MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
698 int64_t V;
699 if (!checkForImmediate(*InitialValue, V))
700 return nullptr;
701 }
703 }
704 if (EndValue->isReg()) {
706 MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
708 int64_t V;
709 if (!checkForImmediate(*EndValue, V))
710 return nullptr;
711 }
713 }
714
715 return computeCount(L, InitialValue, EndValue, IVReg, IVBump, Cmp);
716}
717
718
719
720
721
722CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
723 const MachineOperand *Start,
724 const MachineOperand *End,
726 int64_t IVBump,
727 Comparison::Kind Cmp) const {
733
734 if (Cmp == Comparison::EQ)
735 return nullptr;
736
737
738
739 if (Start->isReg()) {
740 const MachineInstr *StartValInstr = MRI->getVRegDef(Start->getReg());
741 if (StartValInstr && (StartValInstr->getOpcode() == Hexagon::A2_tfrsi ||
742 StartValInstr->getOpcode() == Hexagon::A2_tfrpi))
744 }
745 if (End->isReg()) {
746 const MachineInstr *EndValInstr = MRI->getVRegDef(End->getReg());
747 if (EndValInstr && (EndValInstr->getOpcode() == Hexagon::A2_tfrsi ||
748 EndValInstr->getOpcode() == Hexagon::A2_tfrpi))
750 }
751
752 if (->isReg() &&
->isImm())
753 return nullptr;
755 return nullptr;
756
757 bool CmpLess = Cmp & Comparison::L;
758 bool CmpGreater = Cmp & Comparison::G;
759 bool CmpHasEqual = Cmp & Comparison::EQ;
760
761
762 if (CmpLess && IVBump < 0)
763
764 return nullptr;
765
766 if (CmpGreater && IVBump > 0)
767
768 return nullptr;
769
770
771 LoopFeederMap LoopFeederPhi;
772
773
774
775
776 if (loopCountMayWrapOrUnderFlow(Start, End, Loop->getLoopPreheader(), Loop,
777 LoopFeederPhi))
778 return nullptr;
779
780 if (Start->isImm() && End->isImm()) {
781
782 int64_t StartV = Start->getImm();
783 int64_t EndV = End->getImm();
784 int64_t Dist = EndV - StartV;
785 if (Dist == 0)
786 return nullptr;
787
788 bool Exact = (Dist % IVBump) == 0;
789
790 if (Cmp == Comparison::NE) {
791 if (!Exact)
792 return nullptr;
793 if ((Dist < 0) ^ (IVBump < 0))
794 return nullptr;
795 }
796
797
798
799 if (CmpHasEqual)
800 Dist = Dist > 0 ? Dist+1 : Dist-1;
801
802
803
804
805
806 if ((CmpLess && Dist < 0) || (CmpGreater && Dist > 0))
807 return nullptr;
808
809
810 int64_t Dist1 = (IVBump > 0) ? (Dist + (IVBump - 1)) / IVBump
811 : (-Dist + (-IVBump - 1)) / (-IVBump);
812 assert (Dist1 > 0 && "Fishy thing. Both operands have the same sign.");
813
814 uint64_t Count = Dist1;
815
816 if (Count > 0xFFFFFFFFULL)
817 return nullptr;
818
819 return new CountValue(CountValue::CV_Immediate, Count);
820 }
821
822
823
824
825
826
827
829 return nullptr;
830
831 MachineBasicBlock *PH = MLI->findLoopPreheader(Loop, SpecPreheader);
832 assert (PH && "Should have a preheader by now");
835 if (InsertPos != PH->end())
836 DL = InsertPos->getDebugLoc();
837
838
839
840
841
842
843
844
845 if (IVBump < 0) {
847 IVBump = -IVBump;
849 }
850
851
852
853 bool RegToImm = Start->isReg() && End->isImm();
854 bool RegToReg = Start->isReg() && End->isReg();
855
856 int64_t StartV = 0, EndV = 0;
857 if (Start->isImm())
858 StartV = Start->getImm();
859 if (End->isImm())
860 EndV = End->getImm();
861
862 int64_t AdjV = 0;
863
864
865
866
867
868
869
870
871 if (CmpHasEqual) {
872
873 if (Start->isImm())
874 StartV--;
875 else if (End->isImm())
876 EndV++;
877 else
878 AdjV += 1;
879 }
880
881 if (Cmp != Comparison::NE) {
882 if (Start->isImm())
883 StartV -= (IVBump-1);
884 else if (End->isImm())
885 EndV += (IVBump-1);
886 else
887 AdjV += (IVBump-1);
888 }
889
891 unsigned SR = 0;
892 if (Start->isReg()) {
894 SR = Start->getSubReg();
895 } else {
898 }
899 const TargetRegisterClass *RC = MRI->getRegClass(R);
900
901
902 if (!SR && RC == &Hexagon::DoubleRegsRegClass)
903 return nullptr;
904 const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass;
905
906
908 unsigned DistSR;
909
910
911 if (Start->isImm() && StartV == 0) {
912 DistR = End->getReg();
914 } else {
915 const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::A2_sub) :
916 (RegToImm ? TII->get(Hexagon::A2_subri) :
917 TII->get(Hexagon::A2_addi));
918 if (RegToReg || RegToImm) {
919 Register SubR = MRI->createVirtualRegister(IntRC);
920 MachineInstrBuilder SubIB =
921 BuildMI(*PH, InsertPos, DL, SubD, SubR);
922
923 if (RegToReg)
926 else
929 DistR = SubR;
930 } else {
931
932
933
934 const MachineInstr *EndValInstr = MRI->getVRegDef(End->getReg());
935 if (EndValInstr->getOpcode() == Hexagon::A2_addi &&
939 } else {
940 Register SubR = MRI->createVirtualRegister(IntRC);
941 MachineInstrBuilder SubIB =
942 BuildMI(*PH, InsertPos, DL, SubD, SubR);
945 DistR = SubR;
946 }
947 }
948 DistSR = 0;
949 }
950
951
953 unsigned AdjSR;
954
955 if (AdjV == 0) {
956 AdjR = DistR;
957 AdjSR = DistSR;
958 } else {
959
960 Register AddR = MRI->createVirtualRegister(IntRC);
961 MCInstrDesc const &AddD = TII->get(Hexagon::A2_addi);
962 BuildMI(*PH, InsertPos, DL, AddD, AddR)
963 .addReg(DistR, 0, DistSR)
965
966 AdjR = AddR;
967 AdjSR = 0;
968 }
969
970
972 unsigned CountSR;
973
974 if (IVBump == 1) {
975 CountR = AdjR;
976 CountSR = AdjSR;
977 } else {
978
979 unsigned Shift = Log2_32(IVBump);
980
981
982 Register LsrR = MRI->createVirtualRegister(IntRC);
983 const MCInstrDesc &LsrD = TII->get(Hexagon::S2_lsr_i_r);
984 BuildMI(*PH, InsertPos, DL, LsrD, LsrR)
985 .addReg(AdjR, 0, AdjSR)
987
988 CountR = LsrR;
989 CountSR = 0;
990 }
991
992 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
994 unsigned MuxSR = CountSR;
995
996
997
998 if (!(Start->isImm() && StartV == 0 && Comparison::isUnsigned(Cmp) &&
999 CmpLess) &&
1000 (CmpLess || CmpGreater)) {
1001
1002
1003
1004 Register DistCheckR = MRI->createVirtualRegister(PredRC);
1005 const MCInstrDesc &DistCheckD = TII->get(Hexagon::C2_cmpgti);
1006 BuildMI(*PH, InsertPos, DL, DistCheckD, DistCheckR)
1007 .addReg(DistR, 0, DistSR)
1008 .addImm((CmpLess) ? 0 : -1);
1009
1010
1011
1012
1013 MuxR = MRI->createVirtualRegister(IntRC);
1014 if (CmpLess) {
1015 const MCInstrDesc &MuxD = TII->get(Hexagon::C2_muxir);
1016 BuildMI(*PH, InsertPos, DL, MuxD, MuxR)
1018 .addReg(CountR, 0, CountSR)
1020 } else {
1021 const MCInstrDesc &MuxD = TII->get(Hexagon::C2_muxri);
1022 BuildMI(*PH, InsertPos, DL, MuxD, MuxR)
1025 .addReg(CountR, 0, CountSR);
1026 }
1027 MuxSR = 0;
1028 }
1029
1030 return new CountValue(CountValue::CV_Register, MuxR, MuxSR);
1031}
1032
1033
1034bool HexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI,
1035 bool IsInnerHWLoop) const {
1036
1037
1038 if (MI->getDesc().isCall())
1039 return ->doesNotReturn(*MI);
1040
1041
1042 using namespace Hexagon;
1043
1044 static const Register Regs01[] = { LC0, SA0, LC1, SA1 };
1045 static const Register Regs1[] = { LC1, SA1 };
1046 auto CheckRegs = IsInnerHWLoop ? ArrayRef(Regs01) : ArrayRef(Regs1);
1047 for (Register R : CheckRegs)
1048 if (MI->modifiesRegister(R, TRI))
1049 return true;
1050
1051 return false;
1052}
1053
1054
1055
1056bool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L,
1057 bool IsInnerHWLoop) const {
1060 for (MachineBasicBlock *MBB : L->getBlocks()) {
1061 for (const MachineInstr &MI : *MBB) {
1062 if (isInvalidLoopOperation(&MI, IsInnerHWLoop)) {
1063 LLVM_DEBUG(dbgs() << "\nCannot convert to hw_loop due to:";
1065 return true;
1066 }
1067 }
1068 }
1069 return false;
1070}
1071
1072
1073
1074
1075
1076bool HexagonHardwareLoops::isDead(const MachineInstr *MI,
1077 SmallVectorImpl<MachineInstr *> &DeadPhis) const {
1078
1079 for (const MachineOperand &MO : MI->operands()) {
1081 continue;
1082
1084 if (MRI->use_nodbg_empty(Reg))
1085 continue;
1086
1088
1089
1090
1091
1092 use_nodbg_iterator I = MRI->use_nodbg_begin(Reg);
1093 use_nodbg_iterator End = MRI->use_nodbg_end();
1094 if (std::next(I) != End || ->getParent()->isPHI())
1095 return false;
1096
1097 MachineInstr *OnePhi = I->getParent();
1098 for (const MachineOperand &OPO : OnePhi->operands()) {
1099 if (!OPO.isReg() || !OPO.isDef())
1100 continue;
1101
1102 Register OPReg = OPO.getReg();
1103 use_nodbg_iterator nextJ;
1104 for (use_nodbg_iterator J = MRI->use_nodbg_begin(OPReg);
1105 J != End; J = nextJ) {
1106 nextJ = std::next(J);
1107 MachineOperand &Use = *J;
1108 MachineInstr *UseMI = Use.getParent();
1109
1110
1112 return false;
1113 }
1114 }
1116 }
1117
1118
1119 return true;
1120}
1121
1122void HexagonHardwareLoops::removeIfDead(MachineInstr *MI) {
1123
1124
1128
1129
1130
1131
1132 for (const MachineOperand &MO : MI->operands()) {
1134 continue;
1136
1137
1138 for (MachineOperand &MO :
1142 continue;
1145 }
1146 }
1147
1148 MI->eraseFromParent();
1149 for (unsigned i = 0; i < DeadPhis.size(); ++i)
1150 DeadPhis[i]->eraseFromParent();
1151 }
1152}
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L,
1163 bool &RecL0used,
1164 bool &RecL1used) {
1165
1166 assert(L->getHeader() && "Loop without a header?");
1167
1169 bool L0Used = false;
1170 bool L1Used = false;
1171
1172
1173 for (MachineLoop *I : *L) {
1174 Changed |= convertToHardwareLoop(I, RecL0used, RecL1used);
1175 L0Used |= RecL0used;
1176 L1Used |= RecL1used;
1177 }
1178
1179
1180 if (Changed && L0Used && L1Used)
1182
1183 unsigned LOOP_i;
1184 unsigned LOOP_r;
1185 unsigned ENDLOOP;
1186
1187
1188
1189
1190 unsigned IsInnerHWLoop = 1;
1191
1192 if (L0Used) {
1193 LOOP_i = Hexagon::J2_loop1i;
1194 LOOP_r = Hexagon::J2_loop1r;
1195 ENDLOOP = Hexagon::ENDLOOP1;
1196 IsInnerHWLoop = 0;
1197 } else {
1198 LOOP_i = Hexagon::J2_loop0i;
1199 LOOP_r = Hexagon::J2_loop0r;
1200 ENDLOOP = Hexagon::ENDLOOP0;
1201 }
1202
1203#ifndef NDEBUG
1204
1206 if (Limit >= 0) {
1208 return false;
1209 Counter++;
1210 }
1211#endif
1212
1213
1214 if (containsInvalidInstruction(L, IsInnerHWLoop))
1215 return false;
1216
1217 MachineBasicBlock *LastMBB = L->findLoopControlBlock();
1218
1219 if (!LastMBB)
1220 return false;
1221
1223 if (LastI == LastMBB->end())
1224 return false;
1225
1226
1227 if (!fixupInductionVariable(L))
1228 return false;
1229
1230
1231
1232 MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader);
1233 if (!Preheader) {
1234 Preheader = createPreheaderForLoop(L);
1235 if (!Preheader)
1236 return false;
1237 }
1238
1240
1241 SmallVector<MachineInstr*, 2> OldInsts;
1242
1243 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1244 if (!TripCount)
1245 return false;
1246
1247
1248 if (TripCount->isReg()) {
1249
1250
1251 MachineInstr *TCDef = MRI->getVRegDef(TripCount->getReg());
1252 MachineBasicBlock *BBDef = TCDef->getParent();
1253 if (!MDT->dominates(BBDef, Preheader))
1254 return false;
1255 }
1256
1257
1258 MachineBasicBlock *TopBlock = L->getTopBlock();
1259 MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
1260 MachineBasicBlock *LoopStart = nullptr;
1261 if (ExitingBlock != L->getLoopLatch()) {
1262 MachineBasicBlock *TB = nullptr, *FB = nullptr;
1264
1266 return false;
1267
1268 if (L->contains(TB))
1269 LoopStart = TB;
1270 else if (L->contains(FB))
1271 LoopStart = FB;
1272 else
1273 return false;
1274 }
1275 else
1276 LoopStart = TopBlock;
1277
1278
1279 LLVM_DEBUG(dbgs() << "Change to hardware loop at "; L->dump());
1281 if (InsertPos != Preheader->end())
1282 DL = InsertPos->getDebugLoc();
1283
1284 if (TripCount->isReg()) {
1285
1286 Register CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1287 BuildMI(*Preheader, InsertPos, DL, TII->get(TargetOpcode::COPY), CountReg)
1288 .addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1289
1292 } else {
1293 assert(TripCount->isImm() && "Expecting immediate value for trip count");
1294
1295
1296
1297 int64_t CountImm = TripCount->getImm();
1298 if (->isValidOffset(LOOP_i, CountImm, TRI)) {
1299 Register CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1300 BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
1304 } else
1307 }
1308
1309
1311
1312
1313 DebugLoc LastIDL = LastI->getDebugLoc();
1315
1316
1317
1318
1319 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1320 LastI->getOpcode() == Hexagon::J2_jumpf) {
1321
1322 MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
1323 LastI = LastMBB->erase(LastI);
1324 if (->contains(BranchTarget)) {
1325 if (LastI != LastMBB->end())
1326 LastI = LastMBB->erase(LastI);
1329 }
1330 } else {
1331
1332 LastMBB->erase(LastI);
1333 }
1334 delete TripCount;
1335
1336
1337
1338 for (unsigned i = 0; i < OldInsts.size(); ++i)
1339 removeIfDead(OldInsts[i]);
1340
1341 ++NumHWLoops;
1342
1343
1344
1345
1346 if (L0Used)
1347 RecL1used = true;
1348 else
1349 RecL0used = true;
1350
1351 return true;
1352}
1353
1354bool HexagonHardwareLoops::orderBumpCompare(MachineInstr *BumpI,
1355 MachineInstr *CmpI) {
1356 assert (BumpI != CmpI && "Bump and compare in the same instruction?");
1357
1358 MachineBasicBlock *BB = BumpI->getParent();
1360 return false;
1361
1363
1364
1365 for (instr_iterator I(BumpI), E = BB->instr_end(); I != E; ++I)
1366 if (&*I == CmpI)
1367 return true;
1368
1369
1371 bool FoundBump = false;
1372 instr_iterator CmpIt = CmpI->getIterator(), NextIt = std::next(CmpIt);
1373 for (instr_iterator I = NextIt, E = BB->instr_end(); I != E; ++I) {
1375 for (unsigned i = 0, n = In->getNumOperands(); i < n; ++i) {
1376 MachineOperand &MO = In->getOperand(i);
1378 if (MO.getReg() == PredR)
1379 return false;
1380 }
1381 }
1382
1383 if (In == BumpI) {
1385 FoundBump = true;
1386 break;
1387 }
1388 }
1389 assert (FoundBump && "Cannot determine instruction order");
1390 return FoundBump;
1391}
1392
1393
1394
1395
1396
1397
1398bool HexagonHardwareLoops::isLoopFeeder(MachineLoop *L, MachineBasicBlock *A,
1399 MachineInstr *MI,
1400 const MachineOperand *MO,
1401 LoopFeederMap &LoopFeederPhi) const {
1402 if (LoopFeederPhi.find(MO->getReg()) == LoopFeederPhi.end()) {
1405
1407 return false;
1408 MachineInstr *Def = MRI->getVRegDef(MO->getReg());
1409 LoopFeederPhi.insert(std::make_pair(MO->getReg(), Def));
1410 return true;
1411 } else
1412
1413 return false;
1414}
1415
1416
1417
1418bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1419 MachineInstr *Phi, const MachineOperand *EndVal, MachineBasicBlock *MBB,
1420 MachineLoop *L, LoopFeederMap &LoopFeederPhi) const {
1421 assert(Phi->isPHI() && "Expecting a Phi.");
1422
1423
1424 for (int i = 1, n = Phi->getNumOperands(); i < n; i += 2)
1425 if (isLoopFeeder(L, MBB, Phi, &(Phi->getOperand(i)), LoopFeederPhi))
1426 if (loopCountMayWrapOrUnderFlow(&(Phi->getOperand(i)), EndVal,
1427 Phi->getParent(), L, LoopFeederPhi))
1428 return true;
1429 return false;
1430}
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1447 const MachineOperand *InitVal, const MachineOperand *EndVal,
1448 MachineBasicBlock *MBB, MachineLoop *L,
1449 LoopFeederMap &LoopFeederPhi) const {
1450
1451 if (!InitVal->isReg())
1452 return false;
1453
1454 if (!EndVal->isImm())
1455 return false;
1456
1457
1458
1459 int64_t Imm;
1460 if (checkForImmediate(*InitVal, Imm))
1461 return (EndVal->getImm() == Imm);
1462
1464
1465
1467 return true;
1468
1469 MachineInstr *Def = MRI->getVRegDef(Reg);
1470 if (!Def)
1471 return true;
1472
1473
1474
1475 if (Def->isPHI() && !phiMayWrapOrUnderflow(Def, EndVal, Def->getParent(),
1476 L, LoopFeederPhi))
1477 return false;
1478 if (Def->isCopy() && !loopCountMayWrapOrUnderFlow(&(Def->getOperand(1)),
1479 EndVal, Def->getParent(),
1480 L, LoopFeederPhi))
1481 return false;
1482
1483
1484
1485
1487 E = MRI->use_instr_nodbg_end(); I != E; ++I) {
1490 int64_t CmpMask = 0, CmpValue = 0;
1491
1493 continue;
1494
1495 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
1498 continue;
1499
1500 Comparison::Kind Cmp =
1501 getComparisonKind(MI->getOpcode(), nullptr, nullptr, 0);
1502 if (Cmp == 0)
1503 continue;
1505 Cmp = Comparison::getNegatedComparison(Cmp);
1506 if (CmpReg2 != 0 && CmpReg2 == Reg)
1507 Cmp = Comparison::getSwappedComparison(Cmp);
1508
1509
1510 if (Comparison::isSigned(Cmp))
1511 return false;
1512
1513
1514
1515
1516 if ((Cmp & Comparison::G) || Cmp == Comparison::NE)
1517 return false;
1518 }
1519
1520
1521
1522
1523 if (->isCopy() &&
->isPHI())
1524 return false;
1525
1526 return true;
1527}
1528
1529bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO,
1530 int64_t &Val) const {
1531 if (MO.isImm()) {
1533 return true;
1534 }
1535 if (!MO.isReg())
1536 return false;
1537
1538
1539
1540
1541 int64_t TV;
1542
1544 if (.isVirtual())
1545 return false;
1546 MachineInstr *DI = MRI->getVRegDef(R);
1547 unsigned DOpc = DI->getOpcode();
1548 switch (DOpc) {
1549 case TargetOpcode::COPY:
1550 case Hexagon::A2_tfrsi:
1551 case Hexagon::A2_tfrpi:
1552 case Hexagon::CONST32:
1553 case Hexagon::CONST64:
1554
1555
1556
1557 if (!checkForImmediate(DI->getOperand(1), TV))
1558 return false;
1559 break;
1560 case Hexagon::A2_combineii:
1561 case Hexagon::A4_combineir:
1562 case Hexagon::A4_combineii:
1563 case Hexagon::A4_combineri:
1564 case Hexagon::A2_combinew: {
1565 const MachineOperand &S1 = DI->getOperand(1);
1566 const MachineOperand &S2 = DI->getOperand(2);
1567 int64_t V1, V2;
1568 if (!checkForImmediate(S1, V1) || !checkForImmediate(S2, V2))
1569 return false;
1570 TV = V2 | (static_cast<uint64_t>(V1) << 32);
1571 break;
1572 }
1573 case TargetOpcode::REG_SEQUENCE: {
1574 const MachineOperand &S1 = DI->getOperand(1);
1575 const MachineOperand &S3 = DI->getOperand(3);
1576 int64_t V1, V3;
1577 if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1578 return false;
1581 if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi)
1582 TV = V1 | (V3 << 32);
1583 else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo)
1584 TV = V3 | (V1 << 32);
1585 else
1587 break;
1588 }
1589
1590 default:
1591 return false;
1592 }
1593
1594
1595
1597 case Hexagon::isub_lo:
1598 Val = TV & 0xFFFFFFFFULL;
1599 break;
1600 case Hexagon::isub_hi:
1601 Val = (TV >> 32) & 0xFFFFFFFFULL;
1602 break;
1603 default:
1604 Val = TV;
1605 break;
1606 }
1607 return true;
1608}
1609
1610void HexagonHardwareLoops::setImmediate(MachineOperand &MO, int64_t Val) {
1611 if (MO.isImm()) {
1613 return;
1614 }
1615
1618 MachineInstr *DI = MRI->getVRegDef(R);
1619
1620 const TargetRegisterClass *RC = MRI->getRegClass(R);
1621 Register NewR = MRI->createVirtualRegister(RC);
1622 MachineBasicBlock &B = *DI->getParent();
1626}
1627
1628bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) {
1629 MachineBasicBlock *Header = L->getHeader();
1630 MachineBasicBlock *Latch = L->getLoopLatch();
1631 MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
1632
1633 if (!(Header && Latch && ExitingBlock))
1634 return false;
1635
1636
1637
1638 using RegisterBump = std::pair<Register, int64_t>;
1639 using RegisterInduction = std::pair<Register, RegisterBump>;
1640 using RegisterInductionSet = std::set;
1641
1642
1643 RegisterInductionSet IndRegs;
1644
1645
1646
1647
1649
1650 for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
1651 I != E && I->isPHI(); ++I) {
1653
1654
1655 for (unsigned i = 1, n = Phi->getNumOperands(); i < n; i += 2) {
1656 if (Phi->getOperand(i+1).getMBB() != Latch)
1657 continue;
1658
1659 Register PhiReg = Phi->getOperand(i).getReg();
1660 MachineInstr *DI = MRI->getVRegDef(PhiReg);
1661
1663
1664
1666 MachineOperand &Opnd2 = DI->getOperand(2);
1667 int64_t V;
1668 if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1670 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1671 }
1672 }
1673 }
1674 }
1675
1676 if (IndRegs.empty())
1677 return false;
1678
1679 MachineBasicBlock *TB = nullptr, *FB = nullptr;
1681
1683 if (NotAnalyzed || Cond.empty())
1684 return false;
1685
1686 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1687 MachineBasicBlock *LTB = nullptr, *LFB = nullptr;
1689 bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false);
1690 if (NotAnalyzed)
1691 return false;
1692
1693
1694
1695 if (TB == Latch)
1696 TB = (LTB == Header) ? LTB : LFB;
1697 else
1698 FB = (LTB == Header) ? LTB : LFB;
1699 }
1700 if (TB != Header) {
1701 if (FB != Header) {
1702
1703 return false;
1704 }
1705
1706
1707
1708
1709
1710
1712 return false;
1713 }
1714
1715
1716
1717
1718
1719
1720 unsigned CSz = Cond.size();
1721 if (CSz != 1 && CSz != 2)
1722 return false;
1723
1725 return false;
1726
1728 MachineInstr *PredDef = MRI->getVRegDef(P);
1729
1731 return false;
1732
1733 SmallSet<Register,2> CmpRegs;
1734 MachineOperand *CmpImmOp = nullptr;
1735
1736
1737
1738
1739
1740 for (MachineOperand &MO : PredDef->operands()) {
1741 if (MO.isReg()) {
1742
1743
1745 continue;
1746 if (MO.isUse()) {
1747 if (!isImmediate(MO)) {
1749 continue;
1750 }
1751
1752 if (CmpImmOp)
1753 return false;
1754 CmpImmOp = &MO;
1755 }
1756 } else if (MO.isImm()) {
1757 if (CmpImmOp)
1758 return false;
1759 CmpImmOp = &MO;
1760 }
1761 }
1762
1763 if (CmpRegs.empty())
1764 return false;
1765
1766
1767 for (RegisterInductionSet::iterator I = IndRegs.begin(), E = IndRegs.end();
1769
1770
1771
1772 if (CmpRegs.count(I->first))
1773 return true;
1774
1775
1776
1777
1778 const RegisterBump &RB = I->second;
1779 if (CmpRegs.count(RB.first)) {
1780 if (!CmpImmOp) {
1781
1782
1783 MachineInstr *IndI = nullptr;
1784 MachineInstr *nonIndI = nullptr;
1785 MachineOperand *IndMO = nullptr;
1786 MachineOperand *nonIndMO = nullptr;
1787
1788 for (unsigned i = 1, n = PredDef->getNumOperands(); i < n; ++i) {
1789 MachineOperand &MO = PredDef->getOperand(i);
1790 if (MO.isReg() && MO.getReg() == RB.first) {
1792 << ") = " << *(MRI->getVRegDef(I->first)));
1793 if (IndI)
1794 return false;
1795
1796 IndI = MRI->getVRegDef(I->first);
1797 IndMO = &MO;
1798 } else if (MO.isReg()) {
1800 << ") = " << *(MRI->getVRegDef(MO.getReg())));
1801 if (nonIndI)
1802 return false;
1803
1804 nonIndI = MRI->getVRegDef(MO.getReg());
1805 nonIndMO = &MO;
1806 }
1807 }
1808 if (IndI && nonIndI &&
1809 nonIndI->getOpcode() == Hexagon::A2_addi &&
1812 bool Order = orderBumpCompare(IndI, PredDef);
1813 if (Order) {
1816 return true;
1817 }
1818 }
1819 return false;
1820 }
1821
1822
1823
1824 Comparison::Kind Cmp =
1825 getComparisonKind(PredDef->getOpcode(), nullptr, nullptr, 0);
1826 if (!Cmp || Comparison::isUnsigned(Cmp))
1827 return false;
1828
1829
1830
1831
1832 int64_t CmpImm = getImmediate(*CmpImmOp);
1833 int64_t V = RB.second;
1834
1835 if (((V > 0) && (CmpImm > INT64_MAX - V)) ||
1836 ((V < 0) && (CmpImm < INT64_MIN - V)))
1837 return false;
1838 CmpImm += V;
1839
1840
1841
1842 if (CmpImmOp->isImm() && ->isExtendable(*PredDef) &&
1843 ->isValidOffset(PredDef->getOpcode(), CmpImm, TRI, false))
1844 return false;
1845
1846
1847
1848 MachineInstr *BumpI = MRI->getVRegDef(I->first);
1849 bool Order = orderBumpCompare(BumpI, PredDef);
1850 if (!Order)
1851 return false;
1852
1853
1854 setImmediate(*CmpImmOp, CmpImm);
1855 for (MachineOperand &MO : PredDef->operands()) {
1856 if (MO.isReg() && MO.getReg() == RB.first) {
1858 return true;
1859 }
1860 }
1861 }
1862 }
1863
1864 return false;
1865}
1866
1867
1868MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop(
1869 MachineLoop *L) {
1870 if (MachineBasicBlock *TmpPH = MLI->findLoopPreheader(L, SpecPreheader))
1871 return TmpPH;
1873 return nullptr;
1874
1875 MachineBasicBlock *Header = L->getHeader();
1876 MachineBasicBlock *Latch = L->getLoopLatch();
1877 MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
1878 MachineFunction *MF = Header->getParent();
1880
1881#ifndef NDEBUG
1883 return nullptr;
1884#endif
1885
1886 if (!Latch || !ExitingBlock || Header->hasAddressTaken())
1887 return nullptr;
1888
1890
1891
1892
1893 using MBBVector = std::vector<MachineBasicBlock *>;
1894
1895 MBBVector Preds(Header->pred_begin(), Header->pred_end());
1897 MachineBasicBlock *TB = nullptr, *FB = nullptr;
1898
1900 return nullptr;
1901
1902 for (MachineBasicBlock *PB : Preds) {
1904 if (NotAnalyzed)
1905 return nullptr;
1906 }
1907
1909 MF->insert(Header->getIterator(), NewPH);
1910
1911 if (Header->pred_size() > 2) {
1912
1913
1914
1915
1916
1917 for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
1918 I != E && I->isPHI(); ++I) {
1919 MachineInstr *PN = &*I;
1920
1921 const MCInstrDesc &PD = TII->get(TargetOpcode::PHI);
1922 MachineInstr *NewPN = MF->CreateMachineInstr(PD, DL);
1923 NewPH->insert(NewPH->end(), NewPN);
1924
1926 const TargetRegisterClass *RC = MRI->getRegClass(PR);
1927 Register NewPR = MRI->createVirtualRegister(RC);
1929
1930
1931
1932 for (unsigned i = 1, n = PN->getNumOperands(); i < n; i += 2) {
1936 if (PredB == Latch)
1937 continue;
1938
1943 }
1944
1945
1946
1947 for (int i = PN->getNumOperands()-2; i > 0; i -= 2) {
1949 if (PredB != Latch) {
1952 }
1953 }
1956 }
1957 } else {
1958 assert(Header->pred_size() == 2);
1959
1960
1961
1962
1963
1964
1965 for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
1966 I != E && I->isPHI(); ++I) {
1967 MachineInstr *PN = &*I;
1968 for (unsigned i = 1, n = PN->getNumOperands(); i < n; i += 2) {
1969 MachineOperand &MO = PN->getOperand(i+1);
1970 if (MO.getMBB() != Latch)
1972 }
1973 }
1974 }
1975
1976
1977
1978
1981
1982 TB = FB = nullptr;
1983
1984 for (MachineBasicBlock *PB : Preds) {
1985 if (PB != Latch) {
1988 (void)NotAnalyzed;
1989 assert (!NotAnalyzed && "Should be analyzable!");
1990 if (TB != Header && (Tmp2.empty() || FB != Header))
1992 PB->ReplaceUsesOfBlockWith(Header, NewPH);
1993 }
1994 }
1995
1996
1997
1998 TB = FB = nullptr;
1999 bool LatchNotAnalyzed = TII->analyzeBranch(*Latch, TB, FB, Tmp2, false);
2000 (void)LatchNotAnalyzed;
2001 assert (!LatchNotAnalyzed && "Should be analyzable!");
2002 if (!TB && !FB)
2004
2005
2008
2009 MachineLoop *ParentLoop = L->getParentLoop();
2010 if (ParentLoop)
2012
2013
2014 if (MDT) {
2017 MDT->addNewBlock(NewPH, DHN->getBlock());
2019 }
2020 }
2021 }
2022
2023 return NewPH;
2024}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isSigned(unsigned int Opcode)
static cl::opt< bool > HWCreatePreheader("hexagon-hwloop-preheader", cl::Hidden, cl::init(true), cl::desc("Add a preheader to a hardware loop if one doesn't exist"))
static cl::opt< bool > SpecPreheader("hwloop-spec-preheader", cl::Hidden, cl::desc("Allow speculation of preheader " "instructions"))
static cl::opt< std::string > PHFn("hexagon-hwloop-phfn", cl::Hidden, cl::init(""))
static cl::opt< int > HWLoopLimit("hexagon-max-hwloop", cl::Hidden, cl::init(-1))
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
SmallVector< MachineBasicBlock *, 4 > MBBVector
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
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)
AnalysisUsage & addRequired()
DomTreeNodeBase * getIDom() const
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
FunctionPass class - This class is used to implement most global optimizations.
const HexagonInstrInfo * getInstrInfo() const override
const HexagonRegisterInfo * getRegisterInfo() const override
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
bool isAdd() const
Return true if the instruction is an add instruction.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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 getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
Instructions::iterator instr_iterator
pred_iterator pred_begin()
instr_iterator instr_end()
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
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.
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.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
void setSubReg(unsigned subReg)
unsigned getSubReg() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setMBB(MachineBasicBlock *MBB)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_instr_iterator< true, false, true, true > use_instr_nodbg_iterator
use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk all uses of the specified r...
defusechain_iterator< true, false, true, true, false > use_nodbg_iterator
use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the specified register,...
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
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 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 analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
@ PD
PD - Prefix code for packed double precision vector floating point operations performed in the SSE re...
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonHardwareLoops()
Definition HexagonHardwareLoops.cpp:369
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
@ Sub
Subtraction of integers.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI 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.