LLVM: lib/Target/Hexagon/HexagonBitSimplify.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
32
33#define DEBUG_TYPE "hexbit"
34
35using namespace llvm;
36
38 cl::init(true), cl::desc("Preserve subregisters in tied operands"));
43
45 cl::init(std::numeric_limits::max()));
48 cl::init(std::numeric_limits::max()));
50
53
54namespace {
55
56
57 struct RegisterSet {
59 explicit RegisterSet(unsigned s, bool t = false) : Bits(s, t) {}
61
64 LRU.clear();
65 }
66
67 unsigned count() const {
68 return Bits.count();
69 }
70
71 unsigned find_first() const {
74 return 0;
75 return x2v(First);
76 }
77
78 unsigned find_next(unsigned Prev) const {
79 int Next = Bits.find_next(v2x(Prev));
81 return 0;
82 return x2v(Next);
83 }
84
86 unsigned Idx = v2x(R);
87 ensure(Idx);
88 bool Exists = Bits.test(Idx);
89 Bits.set(Idx);
90 if (!Exists) {
91 LRU.push_back(Idx);
93 unsigned T = LRU.front();
95 LRU.pop_front();
96 }
97 }
98 return *this;
99 }
101 unsigned Idx = v2x(R);
102 if (Idx < Bits.size()) {
103 bool Exists = Bits.test(Idx);
104 Bits.reset(Idx);
105 if (Exists) {
108 LRU.erase(F);
109 }
110 }
111 return *this;
112 }
113
115 for (unsigned R = Rs.find_first(); R; R = Rs.find_next(R))
117 return *this;
118 }
120 for (unsigned R = Rs.find_first(); R; R = Rs.find_next(R))
122 return *this;
123 }
124
125 bool operator[](unsigned R) const {
126 unsigned Idx = v2x(R);
127 return Idx < Bits.size() ? Bits[Idx] : false;
128 }
129 bool has(unsigned R) const {
130 unsigned Idx = v2x(R);
131 if (Idx >= Bits.size())
132 return false;
133 return Bits.test(Idx);
134 }
135
136 bool empty() const {
137 return .any();
138 }
140 return Rs.Bits.subsetOf(Bits);
141 }
143 return Bits.anyCommon(Rs.Bits);
144 }
145
146 private:
147 BitVector Bits;
148 std::deque LRU;
149
150 void ensure(unsigned Idx) {
151 if (Bits.size() <= Idx)
152 Bits.resize(std::max(Idx+1, 32U));
153 }
154
155 static inline unsigned v2x(unsigned v) {
156 return Register(v).virtRegIndex();
157 }
158
159 static inline unsigned x2v(unsigned x) {
160 return Register::index2VirtReg(x);
161 }
162 };
163
164 struct PrintRegSet {
165 PrintRegSet(const RegisterSet &S, const TargetRegisterInfo *RI)
166 : RS(S), TRI(RI) {}
167
168 friend raw_ostream &operator<< (raw_ostream &OS,
169 const PrintRegSet &P);
170
171 private:
173 const TargetRegisterInfo *TRI;
174 };
175
177 const PrintRegSet &P);
179 OS << '{';
180 for (unsigned R = P.RS.find_first(); R; R = P.RS.find_next(R))
182 OS << " }";
183 return OS;
184 }
185
186 class Transformation;
187
189 public:
190 static char ID;
191
192 HexagonBitSimplify() : MachineFunctionPass(ID) {}
193
194 StringRef getPassName() const override {
195 return "Hexagon bit simplification";
196 }
197
198 void getAnalysisUsage(AnalysisUsage &AU) const override {
199 AU.addRequired();
200 AU.addPreserved();
202 }
203
204 bool runOnMachineFunction(MachineFunction &MF) override;
205
206 static void getInstrDefs(const MachineInstr &MI, RegisterSet &Defs);
207 static void getInstrUses(const MachineInstr &MI, RegisterSet &Uses);
208 static bool isEqual(const BitTracker::RegisterCell &RC1, uint16_t B1,
209 const BitTracker::RegisterCell &RC2, uint16_t B2, uint16_t W);
210 static bool isZero(const BitTracker::RegisterCell &RC, uint16_t B,
211 uint16_t W);
212 static bool getConst(const BitTracker::RegisterCell &RC, uint16_t B,
213 uint16_t W, uint64_t &U);
215 MachineRegisterInfo &MRI);
216 static bool getSubregMask(const BitTracker::RegisterRef &RR,
217 unsigned &Begin, unsigned &Width, MachineRegisterInfo &MRI);
218 static bool replaceRegWithSub(Register OldR, Register NewR, unsigned NewSR,
219 MachineRegisterInfo &MRI);
220 static bool replaceSubWithSub(Register OldR, unsigned OldSR, Register NewR,
221 unsigned NewSR, MachineRegisterInfo &MRI);
222 static bool parseRegSequence(const MachineInstr &I,
223 BitTracker::RegisterRef &SL, BitTracker::RegisterRef &SH,
224 const MachineRegisterInfo &MRI);
225
226 static bool getUsedBitsInStore(unsigned Opc, BitVector &Bits,
227 uint16_t Begin);
228 static bool getUsedBits(unsigned Opc, unsigned OpN, BitVector &Bits,
229 uint16_t Begin, const HexagonInstrInfo &HII);
230
231 static const TargetRegisterClass *getFinalVRegClass(
232 const BitTracker::RegisterRef &RR, MachineRegisterInfo &MRI);
233 static bool isTransparentCopy(const BitTracker::RegisterRef &RD,
234 const BitTracker::RegisterRef &RS, MachineRegisterInfo &MRI);
235
236 private:
237 MachineDominatorTree *MDT = nullptr;
238
239 bool visitBlock(MachineBasicBlock &B, Transformation &T, RegisterSet &AVs);
240 static bool hasTiedUse(unsigned Reg, MachineRegisterInfo &MRI,
241 unsigned NewSub = Hexagon::NoSubRegister);
242 };
243
244 using HBS = HexagonBitSimplify;
245
246
247
248
249 class Transformation {
250 public:
251 bool TopDown;
252
253 Transformation(bool TD) : TopDown(TD) {}
254 virtual ~Transformation() = default;
255
256 virtual bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) = 0;
257 };
258
259}
260
261char HexagonBitSimplify::ID = 0;
262
264 "Hexagon bit simplification", false, false)
268
269bool HexagonBitSimplify::visitBlock(MachineBasicBlock &B, Transformation &T,
270 RegisterSet &AVs) {
272
273 if (T.TopDown)
274 Changed = T.processBlock(B, AVs);
275
276 RegisterSet Defs;
278 getInstrDefs(I, Defs);
279 RegisterSet NewAVs = AVs;
280 NewAVs.insert(Defs);
281
283 Changed |= visitBlock(*(DTN->getBlock()), T, NewAVs);
284
285 if (.TopDown)
286 Changed |= T.processBlock(B, AVs);
287
289}
290
291
292
293
294void HexagonBitSimplify::getInstrDefs(const MachineInstr &MI,
295 RegisterSet &Defs) {
296 for (auto &Op : MI.operands()) {
297 if (.isReg() ||
.isDef())
298 continue;
300 if (.isVirtual())
301 continue;
302 Defs.insert(R);
303 }
304}
305
306void HexagonBitSimplify::getInstrUses(const MachineInstr &MI,
308 for (auto &Op : MI.operands()) {
309 if (.isReg() ||
.isUse())
310 continue;
312 if (.isVirtual())
313 continue;
314 Uses.insert(R);
315 }
316}
317
318
319bool HexagonBitSimplify::isEqual(const BitTracker::RegisterCell &RC1,
320 uint16_t B1, const BitTracker::RegisterCell &RC2, uint16_t B2,
321 uint16_t W) {
322 for (uint16_t i = 0; i < W; ++i) {
323
325 return false;
326
328 return false;
329 if (RC1[B1+i] != RC2[B2+i])
330 return false;
331 }
332 return true;
333}
334
335bool HexagonBitSimplify::isZero(const BitTracker::RegisterCell &RC,
336 uint16_t B, uint16_t W) {
338 for (uint16_t i = B; i < B+W; ++i)
339 if (!RC[i].is(0))
340 return false;
341 return true;
342}
343
344bool HexagonBitSimplify::getConst(const BitTracker::RegisterCell &RC,
345 uint16_t B, uint16_t W, uint64_t &U) {
347 int64_t T = 0;
348 for (uint16_t i = B+W; i > B; --i) {
349 const BitTracker::BitValue &BV = RC[i-1];
350 T <<= 1;
351 if (BV.is(1))
352 T |= 1;
353 else if (!BV.is(0))
354 return false;
355 }
357 return true;
358}
359
360bool HexagonBitSimplify::replaceReg(Register OldR, Register NewR,
361 MachineRegisterInfo &MRI) {
363 return false;
364 auto Begin = MRI.use_begin(OldR), End = MRI.use_end();
365 decltype(End) NextI;
366 for (auto I = Begin; I != End; I = NextI) {
367 NextI = std::next(I);
368 I->setReg(NewR);
369 }
370 return Begin != End;
371}
372
373bool HexagonBitSimplify::replaceRegWithSub(Register OldR, Register NewR,
374 unsigned NewSR,
375 MachineRegisterInfo &MRI) {
377 return false;
378 if (hasTiedUse(OldR, MRI, NewSR))
379 return false;
380 auto Begin = MRI.use_begin(OldR), End = MRI.use_end();
381 decltype(End) NextI;
382 for (auto I = Begin; I != End; I = NextI) {
383 NextI = std::next(I);
384 I->setReg(NewR);
385 I->setSubReg(NewSR);
386 }
387 return Begin != End;
388}
389
390bool HexagonBitSimplify::replaceSubWithSub(Register OldR, unsigned OldSR,
391 Register NewR, unsigned NewSR,
392 MachineRegisterInfo &MRI) {
394 return false;
395 if (OldSR != NewSR && hasTiedUse(OldR, MRI, NewSR))
396 return false;
397 auto Begin = MRI.use_begin(OldR), End = MRI.use_end();
398 decltype(End) NextI;
399 for (auto I = Begin; I != End; I = NextI) {
400 NextI = std::next(I);
401 if (I->getSubReg() != OldSR)
402 continue;
403 I->setReg(NewR);
404 I->setSubReg(NewSR);
405 }
406 return Begin != End;
407}
408
409
410
411
412bool HexagonBitSimplify::getSubregMask(const BitTracker::RegisterRef &RR,
413 unsigned &Begin, unsigned &Width, MachineRegisterInfo &MRI) {
414 const TargetRegisterClass *RC = MRI.getRegClass(RR.Reg);
415 if (RR.Sub == 0) {
416 Begin = 0;
417 Width = MRI.getTargetRegisterInfo()->getRegSizeInBits(*RC);
418 return true;
419 }
420
421 Begin = 0;
422
423 switch (RC->getID()) {
424 case Hexagon::DoubleRegsRegClassID:
425 case Hexagon::HvxWRRegClassID:
426 Width = MRI.getTargetRegisterInfo()->getRegSizeInBits(*RC) / 2;
427 if (RR.Sub == Hexagon::isub_hi || RR.Sub == Hexagon::vsub_hi)
428 Begin = Width;
429 break;
430 default:
431 return false;
432 }
433 return true;
434}
435
436
437
438
439bool HexagonBitSimplify::parseRegSequence(const MachineInstr &I,
440 BitTracker::RegisterRef &SL, BitTracker::RegisterRef &SH,
441 const MachineRegisterInfo &MRI) {
442 assert(I.getOpcode() == TargetOpcode::REG_SEQUENCE);
443 unsigned Sub1 = I.getOperand(2).getImm(), Sub2 = I.getOperand(4).getImm();
444 auto &DstRC = *MRI.getRegClass(I.getOperand(0).getReg());
445 auto &HRI = static_cast<const HexagonRegisterInfo&>(
446 *MRI.getTargetRegisterInfo());
447 unsigned SubLo = HRI.getHexagonSubRegIndex(DstRC, Hexagon::ps_sub_lo);
448 unsigned SubHi = HRI.getHexagonSubRegIndex(DstRC, Hexagon::ps_sub_hi);
449 assert((Sub1 == SubLo && Sub2 == SubHi) || (Sub1 == SubHi && Sub2 == SubLo));
450 if (Sub1 == SubLo && Sub2 == SubHi) {
451 SL = I.getOperand(1);
452 SH = I.getOperand(3);
453 return true;
454 }
455 if (Sub1 == SubHi && Sub2 == SubLo) {
456 SH = I.getOperand(1);
457 SL = I.getOperand(3);
458 return true;
459 }
460 return false;
461}
462
463
464
465
466
467
468
469bool HexagonBitSimplify::getUsedBitsInStore(unsigned Opc, BitVector &Bits,
470 uint16_t Begin) {
471 using namespace Hexagon;
472
473 switch (Opc) {
474
475 case S2_storerb_io:
476 case S2_storerbnew_io:
477 case S2_pstorerbt_io:
478 case S2_pstorerbf_io:
479 case S4_pstorerbtnew_io:
480 case S4_pstorerbfnew_io:
481 case S2_pstorerbnewt_io:
482 case S2_pstorerbnewf_io:
483 case S4_pstorerbnewtnew_io:
484 case S4_pstorerbnewfnew_io:
485 case S2_storerb_pi:
486 case S2_storerbnew_pi:
487 case S2_pstorerbt_pi:
488 case S2_pstorerbf_pi:
489 case S2_pstorerbtnew_pi:
490 case S2_pstorerbfnew_pi:
491 case S2_pstorerbnewt_pi:
492 case S2_pstorerbnewf_pi:
493 case S2_pstorerbnewtnew_pi:
494 case S2_pstorerbnewfnew_pi:
495 case S4_storerb_ap:
496 case S4_storerbnew_ap:
497 case S2_storerb_pr:
498 case S2_storerbnew_pr:
499 case S4_storerb_ur:
500 case S4_storerbnew_ur:
501 case S2_storerb_pbr:
502 case S2_storerbnew_pbr:
503 case S2_storerb_pci:
504 case S2_storerbnew_pci:
505 case S2_storerb_pcr:
506 case S2_storerbnew_pcr:
507 case S4_storerb_rr:
508 case S4_storerbnew_rr:
509 case S4_pstorerbt_rr:
510 case S4_pstorerbf_rr:
511 case S4_pstorerbtnew_rr:
512 case S4_pstorerbfnew_rr:
513 case S4_pstorerbnewt_rr:
514 case S4_pstorerbnewf_rr:
515 case S4_pstorerbnewtnew_rr:
516 case S4_pstorerbnewfnew_rr:
517 case S2_storerbgp:
518 case S2_storerbnewgp:
519 case S4_pstorerbt_abs:
520 case S4_pstorerbf_abs:
521 case S4_pstorerbtnew_abs:
522 case S4_pstorerbfnew_abs:
523 case S4_pstorerbnewt_abs:
524 case S4_pstorerbnewf_abs:
525 case S4_pstorerbnewtnew_abs:
526 case S4_pstorerbnewfnew_abs:
527 Bits.set(Begin, Begin+8);
528 return true;
529
530
531 case S2_storerh_io:
532 case S2_storerhnew_io:
533 case S2_pstorerht_io:
534 case S2_pstorerhf_io:
535 case S4_pstorerhtnew_io:
536 case S4_pstorerhfnew_io:
537 case S2_pstorerhnewt_io:
538 case S2_pstorerhnewf_io:
539 case S4_pstorerhnewtnew_io:
540 case S4_pstorerhnewfnew_io:
541 case S2_storerh_pi:
542 case S2_storerhnew_pi:
543 case S2_pstorerht_pi:
544 case S2_pstorerhf_pi:
545 case S2_pstorerhtnew_pi:
546 case S2_pstorerhfnew_pi:
547 case S2_pstorerhnewt_pi:
548 case S2_pstorerhnewf_pi:
549 case S2_pstorerhnewtnew_pi:
550 case S2_pstorerhnewfnew_pi:
551 case S4_storerh_ap:
552 case S4_storerhnew_ap:
553 case S2_storerh_pr:
554 case S2_storerhnew_pr:
555 case S4_storerh_ur:
556 case S4_storerhnew_ur:
557 case S2_storerh_pbr:
558 case S2_storerhnew_pbr:
559 case S2_storerh_pci:
560 case S2_storerhnew_pci:
561 case S2_storerh_pcr:
562 case S2_storerhnew_pcr:
563 case S4_storerh_rr:
564 case S4_pstorerht_rr:
565 case S4_pstorerhf_rr:
566 case S4_pstorerhtnew_rr:
567 case S4_pstorerhfnew_rr:
568 case S4_storerhnew_rr:
569 case S4_pstorerhnewt_rr:
570 case S4_pstorerhnewf_rr:
571 case S4_pstorerhnewtnew_rr:
572 case S4_pstorerhnewfnew_rr:
573 case S2_storerhgp:
574 case S2_storerhnewgp:
575 case S4_pstorerht_abs:
576 case S4_pstorerhf_abs:
577 case S4_pstorerhtnew_abs:
578 case S4_pstorerhfnew_abs:
579 case S4_pstorerhnewt_abs:
580 case S4_pstorerhnewf_abs:
581 case S4_pstorerhnewtnew_abs:
582 case S4_pstorerhnewfnew_abs:
583 Bits.set(Begin, Begin+16);
584 return true;
585
586
587 case S2_storerf_io:
588 case S2_pstorerft_io:
589 case S2_pstorerff_io:
590 case S4_pstorerftnew_io:
591 case S4_pstorerffnew_io:
592 case S2_storerf_pi:
593 case S2_pstorerft_pi:
594 case S2_pstorerff_pi:
595 case S2_pstorerftnew_pi:
596 case S2_pstorerffnew_pi:
597 case S4_storerf_ap:
598 case S2_storerf_pr:
599 case S4_storerf_ur:
600 case S2_storerf_pbr:
601 case S2_storerf_pci:
602 case S2_storerf_pcr:
603 case S4_storerf_rr:
604 case S4_pstorerft_rr:
605 case S4_pstorerff_rr:
606 case S4_pstorerftnew_rr:
607 case S4_pstorerffnew_rr:
608 case S2_storerfgp:
609 case S4_pstorerft_abs:
610 case S4_pstorerff_abs:
611 case S4_pstorerftnew_abs:
612 case S4_pstorerffnew_abs:
613 Bits.set(Begin+16, Begin+32);
614 return true;
615 }
616
617 return false;
618}
619
620
621
622
623
624
625
626
627
628bool HexagonBitSimplify::getUsedBits(unsigned Opc, unsigned OpN,
629 BitVector &Bits, uint16_t Begin, const HexagonInstrInfo &HII) {
630 using namespace Hexagon;
631
632 const MCInstrDesc &D = HII.get(Opc);
633 if (D.mayStore()) {
634 if (OpN == D.getNumOperands()-1)
635 return getUsedBitsInStore(Opc, Bits, Begin);
636 return false;
637 }
638
639 switch (Opc) {
640
641 case A2_sxtb:
642 case A2_zxtb:
643 case A4_cmpbeqi:
644 case A4_cmpbgti:
645 case A4_cmpbgtui:
646 if (OpN == 1) {
647 Bits.set(Begin, Begin+8);
648 return true;
649 }
650 break;
651
652
653 case A2_aslh:
654 case A2_sxth:
655 case A2_zxth:
656 case A4_cmpheqi:
657 case A4_cmphgti:
658 case A4_cmphgtui:
659 if (OpN == 1) {
660 Bits.set(Begin, Begin+16);
661 return true;
662 }
663 break;
664
665
666 case A2_asrh:
667 if (OpN == 1) {
668 Bits.set(Begin+16, Begin+32);
669 return true;
670 }
671 break;
672
673
674 case A4_cmpbeq:
675 case A4_cmpbgt:
676 case A4_cmpbgtu:
677 if (OpN == 1) {
678 Bits.set(Begin, Begin+8);
679 return true;
680 }
681 break;
682
683
684 case A4_cmpheq:
685 case A4_cmphgt:
686 case A4_cmphgtu:
687 case A2_addh_h16_ll:
688 case A2_addh_h16_sat_ll:
689 case A2_addh_l16_ll:
690 case A2_addh_l16_sat_ll:
691 case A2_combine_ll:
692 case A2_subh_h16_ll:
693 case A2_subh_h16_sat_ll:
694 case A2_subh_l16_ll:
695 case A2_subh_l16_sat_ll:
696 case M2_mpy_acc_ll_s0:
697 case M2_mpy_acc_ll_s1:
698 case M2_mpy_acc_sat_ll_s0:
699 case M2_mpy_acc_sat_ll_s1:
700 case M2_mpy_ll_s0:
701 case M2_mpy_ll_s1:
702 case M2_mpy_nac_ll_s0:
703 case M2_mpy_nac_ll_s1:
704 case M2_mpy_nac_sat_ll_s0:
705 case M2_mpy_nac_sat_ll_s1:
706 case M2_mpy_rnd_ll_s0:
707 case M2_mpy_rnd_ll_s1:
708 case M2_mpy_sat_ll_s0:
709 case M2_mpy_sat_ll_s1:
710 case M2_mpy_sat_rnd_ll_s0:
711 case M2_mpy_sat_rnd_ll_s1:
712 case M2_mpyd_acc_ll_s0:
713 case M2_mpyd_acc_ll_s1:
714 case M2_mpyd_ll_s0:
715 case M2_mpyd_ll_s1:
716 case M2_mpyd_nac_ll_s0:
717 case M2_mpyd_nac_ll_s1:
718 case M2_mpyd_rnd_ll_s0:
719 case M2_mpyd_rnd_ll_s1:
720 case M2_mpyu_acc_ll_s0:
721 case M2_mpyu_acc_ll_s1:
722 case M2_mpyu_ll_s0:
723 case M2_mpyu_ll_s1:
724 case M2_mpyu_nac_ll_s0:
725 case M2_mpyu_nac_ll_s1:
726 case M2_mpyud_acc_ll_s0:
727 case M2_mpyud_acc_ll_s1:
728 case M2_mpyud_ll_s0:
729 case M2_mpyud_ll_s1:
730 case M2_mpyud_nac_ll_s0:
731 case M2_mpyud_nac_ll_s1:
732 if (OpN == 1 || OpN == 2) {
733 Bits.set(Begin, Begin+16);
734 return true;
735 }
736 break;
737
738
739 case A2_addh_h16_lh:
740 case A2_addh_h16_sat_lh:
741 case A2_combine_lh:
742 case A2_subh_h16_lh:
743 case A2_subh_h16_sat_lh:
744 case M2_mpy_acc_lh_s0:
745 case M2_mpy_acc_lh_s1:
746 case M2_mpy_acc_sat_lh_s0:
747 case M2_mpy_acc_sat_lh_s1:
748 case M2_mpy_lh_s0:
749 case M2_mpy_lh_s1:
750 case M2_mpy_nac_lh_s0:
751 case M2_mpy_nac_lh_s1:
752 case M2_mpy_nac_sat_lh_s0:
753 case M2_mpy_nac_sat_lh_s1:
754 case M2_mpy_rnd_lh_s0:
755 case M2_mpy_rnd_lh_s1:
756 case M2_mpy_sat_lh_s0:
757 case M2_mpy_sat_lh_s1:
758 case M2_mpy_sat_rnd_lh_s0:
759 case M2_mpy_sat_rnd_lh_s1:
760 case M2_mpyd_acc_lh_s0:
761 case M2_mpyd_acc_lh_s1:
762 case M2_mpyd_lh_s0:
763 case M2_mpyd_lh_s1:
764 case M2_mpyd_nac_lh_s0:
765 case M2_mpyd_nac_lh_s1:
766 case M2_mpyd_rnd_lh_s0:
767 case M2_mpyd_rnd_lh_s1:
768 case M2_mpyu_acc_lh_s0:
769 case M2_mpyu_acc_lh_s1:
770 case M2_mpyu_lh_s0:
771 case M2_mpyu_lh_s1:
772 case M2_mpyu_nac_lh_s0:
773 case M2_mpyu_nac_lh_s1:
774 case M2_mpyud_acc_lh_s0:
775 case M2_mpyud_acc_lh_s1:
776 case M2_mpyud_lh_s0:
777 case M2_mpyud_lh_s1:
778 case M2_mpyud_nac_lh_s0:
779 case M2_mpyud_nac_lh_s1:
780
781 case A2_addh_l16_hl:
782 case A2_addh_l16_sat_hl:
783 case A2_subh_l16_hl:
784 case A2_subh_l16_sat_hl:
785 if (OpN == 1) {
786 Bits.set(Begin, Begin+16);
787 return true;
788 }
789 if (OpN == 2) {
790 Bits.set(Begin+16, Begin+32);
791 return true;
792 }
793 break;
794
795
796 case A2_addh_h16_hl:
797 case A2_addh_h16_sat_hl:
798 case A2_combine_hl:
799 case A2_subh_h16_hl:
800 case A2_subh_h16_sat_hl:
801 case M2_mpy_acc_hl_s0:
802 case M2_mpy_acc_hl_s1:
803 case M2_mpy_acc_sat_hl_s0:
804 case M2_mpy_acc_sat_hl_s1:
805 case M2_mpy_hl_s0:
806 case M2_mpy_hl_s1:
807 case M2_mpy_nac_hl_s0:
808 case M2_mpy_nac_hl_s1:
809 case M2_mpy_nac_sat_hl_s0:
810 case M2_mpy_nac_sat_hl_s1:
811 case M2_mpy_rnd_hl_s0:
812 case M2_mpy_rnd_hl_s1:
813 case M2_mpy_sat_hl_s0:
814 case M2_mpy_sat_hl_s1:
815 case M2_mpy_sat_rnd_hl_s0:
816 case M2_mpy_sat_rnd_hl_s1:
817 case M2_mpyd_acc_hl_s0:
818 case M2_mpyd_acc_hl_s1:
819 case M2_mpyd_hl_s0:
820 case M2_mpyd_hl_s1:
821 case M2_mpyd_nac_hl_s0:
822 case M2_mpyd_nac_hl_s1:
823 case M2_mpyd_rnd_hl_s0:
824 case M2_mpyd_rnd_hl_s1:
825 case M2_mpyu_acc_hl_s0:
826 case M2_mpyu_acc_hl_s1:
827 case M2_mpyu_hl_s0:
828 case M2_mpyu_hl_s1:
829 case M2_mpyu_nac_hl_s0:
830 case M2_mpyu_nac_hl_s1:
831 case M2_mpyud_acc_hl_s0:
832 case M2_mpyud_acc_hl_s1:
833 case M2_mpyud_hl_s0:
834 case M2_mpyud_hl_s1:
835 case M2_mpyud_nac_hl_s0:
836 case M2_mpyud_nac_hl_s1:
837 if (OpN == 1) {
838 Bits.set(Begin+16, Begin+32);
839 return true;
840 }
841 if (OpN == 2) {
842 Bits.set(Begin, Begin+16);
843 return true;
844 }
845 break;
846
847
848 case A2_addh_h16_hh:
849 case A2_addh_h16_sat_hh:
850 case A2_combine_hh:
851 case A2_subh_h16_hh:
852 case A2_subh_h16_sat_hh:
853 case M2_mpy_acc_hh_s0:
854 case M2_mpy_acc_hh_s1:
855 case M2_mpy_acc_sat_hh_s0:
856 case M2_mpy_acc_sat_hh_s1:
857 case M2_mpy_hh_s0:
858 case M2_mpy_hh_s1:
859 case M2_mpy_nac_hh_s0:
860 case M2_mpy_nac_hh_s1:
861 case M2_mpy_nac_sat_hh_s0:
862 case M2_mpy_nac_sat_hh_s1:
863 case M2_mpy_rnd_hh_s0:
864 case M2_mpy_rnd_hh_s1:
865 case M2_mpy_sat_hh_s0:
866 case M2_mpy_sat_hh_s1:
867 case M2_mpy_sat_rnd_hh_s0:
868 case M2_mpy_sat_rnd_hh_s1:
869 case M2_mpyd_acc_hh_s0:
870 case M2_mpyd_acc_hh_s1:
871 case M2_mpyd_hh_s0:
872 case M2_mpyd_hh_s1:
873 case M2_mpyd_nac_hh_s0:
874 case M2_mpyd_nac_hh_s1:
875 case M2_mpyd_rnd_hh_s0:
876 case M2_mpyd_rnd_hh_s1:
877 case M2_mpyu_acc_hh_s0:
878 case M2_mpyu_acc_hh_s1:
879 case M2_mpyu_hh_s0:
880 case M2_mpyu_hh_s1:
881 case M2_mpyu_nac_hh_s0:
882 case M2_mpyu_nac_hh_s1:
883 case M2_mpyud_acc_hh_s0:
884 case M2_mpyud_acc_hh_s1:
885 case M2_mpyud_hh_s0:
886 case M2_mpyud_hh_s1:
887 case M2_mpyud_nac_hh_s0:
888 case M2_mpyud_nac_hh_s1:
889 if (OpN == 1 || OpN == 2) {
890 Bits.set(Begin+16, Begin+32);
891 return true;
892 }
893 break;
894 }
895
896 return false;
897}
898
899
900
901
902const TargetRegisterClass *HexagonBitSimplify::getFinalVRegClass(
903 const BitTracker::RegisterRef &RR, MachineRegisterInfo &MRI) {
905 return nullptr;
906 auto *RC = MRI.getRegClass(RR.Reg);
907 if (RR.Sub == 0)
908 return RC;
909 auto &HRI = static_cast<const HexagonRegisterInfo&>(
910 *MRI.getTargetRegisterInfo());
911
912 auto VerifySR = [&HRI] (const TargetRegisterClass *RC, unsigned Sub) -> void {
913 (void)HRI;
916 };
917
918 switch (RC->getID()) {
919 case Hexagon::DoubleRegsRegClassID:
920 VerifySR(RC, RR.Sub);
921 return &Hexagon::IntRegsRegClass;
922 case Hexagon::HvxWRRegClassID:
923 VerifySR(RC, RR.Sub);
924 return &Hexagon::HvxVRRegClass;
925 }
926 return nullptr;
927}
928
929
930
931
932
933bool HexagonBitSimplify::isTransparentCopy(const BitTracker::RegisterRef &RD,
934 const BitTracker::RegisterRef &RS, MachineRegisterInfo &MRI) {
936 return false;
937
938 auto *DRC = getFinalVRegClass(RD, MRI);
939 if (!DRC)
940 return false;
941
942 return DRC == getFinalVRegClass(RS, MRI);
943}
944
945bool HexagonBitSimplify::hasTiedUse(unsigned Reg, MachineRegisterInfo &MRI,
946 unsigned NewSub) {
948 return false;
950 [NewSub] (const MachineOperand &Op) -> bool {
951 return Op.getSubReg() != NewSub && Op.isTied();
952 });
953}
954
955namespace {
956
957 class DeadCodeElimination {
958 public:
959 DeadCodeElimination(MachineFunction &mf, MachineDominatorTree &mdt)
960 : MF(mf), HII(*MF.getSubtarget().getInstrInfo()),
961 MDT(mdt), MRI(mf.getRegInfo()) {}
962
963 bool run() {
965 }
966
967 private:
968 bool isDead(unsigned R) const;
970
971 MachineFunction &MF;
972 const HexagonInstrInfo &HII;
973 MachineDominatorTree &MDT;
974 MachineRegisterInfo &MRI;
975 };
976
977}
978
979bool DeadCodeElimination::isDead(unsigned R) const {
980 for (const MachineOperand &MO : MRI.use_operands(R)) {
981 const MachineInstr *UseI = MO.getParent();
983 continue;
984 if (UseI->isPHI()) {
987 if (DR == R)
988 continue;
989 }
990 return false;
991 }
992 return true;
993}
994
997
999 Changed |= runOnNode(DTN);
1000
1001 MachineBasicBlock *B = N->getBlock();
1002 std::vector<MachineInstr*> Instrs;
1004 Instrs.push_back(&MI);
1005
1006 for (auto *MI : Instrs) {
1007 unsigned Opc = MI->getOpcode();
1008
1009
1010 if (Opc == TargetOpcode::LIFETIME_START ||
1011 Opc == TargetOpcode::LIFETIME_END)
1012 continue;
1013 bool Store = false;
1014 if (MI->isInlineAsm())
1015 continue;
1016
1017 if (->isPHI() &&
->isSafeToMove(Store))
1018 continue;
1019
1020 bool AllDead = true;
1021 SmallVector<unsigned,2> Regs;
1022 for (auto &Op : MI->operands()) {
1023 if (.isReg() ||
.isDef())
1024 continue;
1026 if (.isVirtual() ||
(R)) {
1027 AllDead = false;
1028 break;
1029 }
1031 }
1032 if (!AllDead)
1033 continue;
1034
1036 for (unsigned Reg : Regs)
1037 MRI.markUsesInDebugValueAsUndef(Reg);
1039 }
1040
1042}
1043
1044namespace {
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 class RedundantInstrElimination : public Transformation {
1057 public:
1058 RedundantInstrElimination(BitTracker &bt, const HexagonInstrInfo &hii,
1059 const HexagonRegisterInfo &hri, MachineRegisterInfo &mri)
1060 : Transformation(true), HII(hii), HRI(hri), MRI(mri), BT(bt) {}
1061
1062 bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1063
1064 private:
1065 bool isLossyShiftLeft(const MachineInstr &MI, unsigned OpN,
1066 unsigned &LostB, unsigned &LostE);
1067 bool isLossyShiftRight(const MachineInstr &MI, unsigned OpN,
1068 unsigned &LostB, unsigned &LostE);
1069 bool computeUsedBits(unsigned Reg, BitVector &Bits);
1070 bool computeUsedBits(const MachineInstr &MI, unsigned OpN, BitVector &Bits,
1071 uint16_t Begin);
1072 bool usedBitsEqual(BitTracker::RegisterRef RD, BitTracker::RegisterRef RS);
1073
1074 const HexagonInstrInfo &HII;
1075 const HexagonRegisterInfo &HRI;
1076 MachineRegisterInfo &MRI;
1077 BitTracker &BT;
1078 };
1079
1080}
1081
1082
1083
1084
1085bool RedundantInstrElimination::isLossyShiftLeft(const MachineInstr &MI,
1086 unsigned OpN, unsigned &LostB, unsigned &LostE) {
1087 using namespace Hexagon;
1088
1089 unsigned Opc = MI.getOpcode();
1090 unsigned ImN, RegN, Width;
1091 switch (Opc) {
1092 case S2_asl_i_p:
1093 ImN = 2;
1094 RegN = 1;
1095 Width = 64;
1096 break;
1097 case S2_asl_i_p_acc:
1098 case S2_asl_i_p_and:
1099 case S2_asl_i_p_nac:
1100 case S2_asl_i_p_or:
1101 case S2_asl_i_p_xacc:
1102 ImN = 3;
1103 RegN = 2;
1104 Width = 64;
1105 break;
1106 case S2_asl_i_r:
1107 ImN = 2;
1108 RegN = 1;
1109 Width = 32;
1110 break;
1111 case S2_addasl_rrri:
1112 case S4_andi_asl_ri:
1113 case S4_ori_asl_ri:
1114 case S4_addi_asl_ri:
1115 case S4_subi_asl_ri:
1116 case S2_asl_i_r_acc:
1117 case S2_asl_i_r_and:
1118 case S2_asl_i_r_nac:
1119 case S2_asl_i_r_or:
1120 case S2_asl_i_r_sat:
1121 case S2_asl_i_r_xacc:
1122 ImN = 3;
1123 RegN = 2;
1124 Width = 32;
1125 break;
1126 default:
1127 return false;
1128 }
1129
1130 if (RegN != OpN)
1131 return false;
1132
1133 assert(MI.getOperand(ImN).isImm());
1134 unsigned S = MI.getOperand(ImN).getImm();
1135 if (S == 0)
1136 return false;
1137 LostB = Width-S;
1138 LostE = Width;
1139 return true;
1140}
1141
1142
1143
1144
1145bool RedundantInstrElimination::isLossyShiftRight(const MachineInstr &MI,
1146 unsigned OpN, unsigned &LostB, unsigned &LostE) {
1147 using namespace Hexagon;
1148
1149 unsigned Opc = MI.getOpcode();
1150 unsigned ImN, RegN;
1151 switch (Opc) {
1152 case S2_asr_i_p:
1153 case S2_lsr_i_p:
1154 ImN = 2;
1155 RegN = 1;
1156 break;
1157 case S2_asr_i_p_acc:
1158 case S2_asr_i_p_and:
1159 case S2_asr_i_p_nac:
1160 case S2_asr_i_p_or:
1161 case S2_lsr_i_p_acc:
1162 case S2_lsr_i_p_and:
1163 case S2_lsr_i_p_nac:
1164 case S2_lsr_i_p_or:
1165 case S2_lsr_i_p_xacc:
1166 ImN = 3;
1167 RegN = 2;
1168 break;
1169 case S2_asr_i_r:
1170 case S2_lsr_i_r:
1171 ImN = 2;
1172 RegN = 1;
1173 break;
1174 case S4_andi_lsr_ri:
1175 case S4_ori_lsr_ri:
1176 case S4_addi_lsr_ri:
1177 case S4_subi_lsr_ri:
1178 case S2_asr_i_r_acc:
1179 case S2_asr_i_r_and:
1180 case S2_asr_i_r_nac:
1181 case S2_asr_i_r_or:
1182 case S2_lsr_i_r_acc:
1183 case S2_lsr_i_r_and:
1184 case S2_lsr_i_r_nac:
1185 case S2_lsr_i_r_or:
1186 case S2_lsr_i_r_xacc:
1187 ImN = 3;
1188 RegN = 2;
1189 break;
1190
1191 default:
1192 return false;
1193 }
1194
1195 if (RegN != OpN)
1196 return false;
1197
1198 assert(MI.getOperand(ImN).isImm());
1199 unsigned S = MI.getOperand(ImN).getImm();
1200 LostB = 0;
1201 LostE = S;
1202 return true;
1203}
1204
1205
1206
1207
1208
1209bool RedundantInstrElimination::computeUsedBits(unsigned Reg, BitVector &Bits) {
1210 BitVector Used(Bits.size());
1212 std::vector Pending;
1213 Pending.push_back(Reg);
1214
1215 for (unsigned i = 0; i < Pending.size(); ++i) {
1216 unsigned R = Pending[i];
1217 if (Visited.has(R))
1218 continue;
1219 Visited.insert(R);
1220 for (auto I = MRI.use_begin(R), E = MRI.use_end(); I != E; ++I) {
1221 BitTracker::RegisterRef UR = *I;
1223 if (!HBS::getSubregMask(UR, B, W, MRI))
1224 return false;
1225 MachineInstr &UseI = *I->getParent();
1229 return false;
1230 Pending.push_back(DefR);
1231 } else {
1232 if (!computeUsedBits(UseI, I.getOperandNo(), Used, B))
1233 return false;
1234 }
1235 }
1236 }
1238 return true;
1239}
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255bool RedundantInstrElimination::computeUsedBits(const MachineInstr &MI,
1256 unsigned OpN, BitVector &Bits, uint16_t Begin) {
1257 unsigned Opc = MI.getOpcode();
1258 BitVector T(Bits.size());
1259 bool GotBits = HBS::getUsedBits(Opc, OpN, T, Begin, HII);
1260
1261
1262
1263 unsigned LB, LE;
1264 if (isLossyShiftLeft(MI, OpN, LB, LE) || isLossyShiftRight(MI, OpN, LB, LE)) {
1265 assert(MI.getOperand(OpN).isReg());
1266 BitTracker::RegisterRef RR = MI.getOperand(OpN);
1267 const TargetRegisterClass *RC = HBS::getFinalVRegClass(RR, MRI);
1268 uint16_t Width = HRI.getRegSizeInBits(*RC);
1269
1270 if (!GotBits)
1271 T.set(Begin, Begin+Width);
1272 assert(LB <= LE && LB < Width && LE <= Width);
1273 T.reset(Begin+LB, Begin+LE);
1274 GotBits = true;
1275 }
1276 if (GotBits)
1278 return GotBits;
1279}
1280
1281
1282
1283bool RedundantInstrElimination::usedBitsEqual(BitTracker::RegisterRef RD,
1284 BitTracker::RegisterRef RS) {
1285 const BitTracker::RegisterCell &DC = BT.lookup(RD.Reg);
1286 const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
1287
1288 unsigned DB, DW;
1289 if (!HBS::getSubregMask(RD, DB, DW, MRI))
1290 return false;
1291 unsigned SB, SW;
1292 if (!HBS::getSubregMask(RS, SB, SW, MRI))
1293 return false;
1294 if (SW != DW)
1295 return false;
1296
1298 if (!computeUsedBits(RD.Reg, Used))
1299 return false;
1300
1301 for (unsigned i = 0; i != DW; ++i)
1302 if (Used[i+DB] && DC[DB+i] != SC[SB+i])
1303 return false;
1304 return true;
1305}
1306
1307bool RedundantInstrElimination::processBlock(MachineBasicBlock &B,
1310 return false;
1312
1313 for (auto I = B.begin(), E = B.end(); I != E; ++I) {
1315
1316 if (MI->getOpcode() == TargetOpcode::COPY)
1317 continue;
1318 if (MI->isPHI() || MI->hasUnmodeledSideEffects() || MI->isInlineAsm())
1319 continue;
1320 unsigned NumD = MI->getDesc().getNumDefs();
1321 if (NumD != 1)
1322 continue;
1323
1324 BitTracker::RegisterRef RD = MI->getOperand(0);
1326 continue;
1327 const BitTracker::RegisterCell &DC = BT.lookup(RD.Reg);
1329
1330
1331 for (auto &Op : MI->uses()) {
1332 if (.isReg())
1333 continue;
1334 BitTracker::RegisterRef RS = Op;
1336 continue;
1337 if (!HBS::isTransparentCopy(RD, RS, MRI))
1338 continue;
1339
1340 unsigned BN, BW;
1341 if (!HBS::getSubregMask(RS, BN, BW, MRI))
1342 continue;
1343
1344 const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
1345 if (!usedBitsEqual(RD, RS) && !HBS::isEqual(DC, 0, SC, BN, BW))
1346 continue;
1347
1348
1350 const TargetRegisterClass *FRC = HBS::getFinalVRegClass(RD, MRI);
1351 Register NewR = MRI.createVirtualRegister(FRC);
1352 MachineInstr *CopyI =
1353 BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
1355 HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
1356
1357
1358
1359
1360
1361
1362
1363
1364
1367 break;
1368 }
1369 }
1370
1372}
1373
1374namespace {
1375
1376
1377
1378 class ConstGeneration : public Transformation {
1379 public:
1380 ConstGeneration(BitTracker &bt, const HexagonInstrInfo &hii,
1381 MachineRegisterInfo &mri)
1382 : Transformation(true), HII(hii), MRI(mri), BT(bt) {}
1383
1384 bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1385 static bool isTfrConst(const MachineInstr &MI);
1386
1387 private:
1388 Register genTfrConst(const TargetRegisterClass *RC, int64_t C,
1391
1392 const HexagonInstrInfo &HII;
1393 MachineRegisterInfo &MRI;
1394 BitTracker &BT;
1395 };
1396
1397}
1398
1399bool ConstGeneration::isTfrConst(const MachineInstr &MI) {
1400 unsigned Opc = MI.getOpcode();
1401 switch (Opc) {
1402 case Hexagon::A2_combineii:
1403 case Hexagon::A4_combineii:
1404 case Hexagon::A2_tfrsi:
1405 case Hexagon::A2_tfrpi:
1406 case Hexagon::PS_true:
1407 case Hexagon::PS_false:
1408 case Hexagon::CONST32:
1409 case Hexagon::CONST64:
1410 return true;
1411 }
1412 return false;
1413}
1414
1415
1416
1417Register ConstGeneration::genTfrConst(const TargetRegisterClass *RC, int64_t C,
1418 MachineBasicBlock &B,
1422 if (RC == &Hexagon::IntRegsRegClass) {
1423 BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrsi), Reg)
1425 return Reg;
1426 }
1427
1428 if (RC == &Hexagon::DoubleRegsRegClass) {
1430 BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrpi), Reg)
1432 return Reg;
1433 }
1434
1437 unsigned Opc = isInt<8>(Lo) ? Hexagon::A2_combineii
1438 : Hexagon::A4_combineii;
1442 return Reg;
1443 }
1444 MachineFunction *MF = B.getParent();
1445 auto &HST = MF->getSubtarget();
1446
1447
1448 if (!HST.isTinyCore() ||
1450 BuildMI(B, At, DL, HII.get(Hexagon::CONST64), Reg)
1452 return Reg;
1453 }
1454 }
1455
1456 if (RC == &Hexagon::PredRegsRegClass) {
1457 unsigned Opc;
1458 if (C == 0)
1459 Opc = Hexagon::PS_false;
1460 else if ((C & 0xFF) == 0xFF)
1461 Opc = Hexagon::PS_true;
1462 else
1463 return 0;
1465 return Reg;
1466 }
1467
1468 return 0;
1469}
1470
1471bool ConstGeneration::processBlock(MachineBasicBlock &B, const RegisterSet&) {
1473 return false;
1476
1477 for (auto I = B.begin(), E = B.end(); I != E; ++I) {
1478 if (isTfrConst(*I))
1479 continue;
1480 Defs.clear();
1481 HBS::getInstrDefs(*I, Defs);
1482 if (Defs.count() != 1)
1483 continue;
1484 Register DR = Defs.find_first();
1486 continue;
1487 uint64_t U;
1488 const BitTracker::RegisterCell &DRC = BT.lookup(DR);
1489 if (HBS::getConst(DRC, 0, DRC.width(), U)) {
1492 auto At = I->isPHI() ? B.getFirstNonPHI() : I;
1493 Register ImmReg = genTfrConst(MRI.getRegClass(DR), C, B, At, DL);
1494 if (ImmReg) {
1495 HBS::replaceReg(DR, ImmReg, MRI);
1498 }
1499 }
1500 }
1502}
1503
1504namespace {
1505
1506
1507
1508
1509 class CopyGeneration : public Transformation {
1510 public:
1511 CopyGeneration(BitTracker &bt, const HexagonInstrInfo &hii,
1512 const HexagonRegisterInfo &hri, MachineRegisterInfo &mri)
1513 : Transformation(true), HII(hii), HRI(hri), MRI(mri), BT(bt) {}
1514
1515 bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1516
1517 private:
1518 bool findMatch(const BitTracker::RegisterRef &Inp,
1519 BitTracker::RegisterRef &Out, const RegisterSet &AVs);
1520
1521 const HexagonInstrInfo &HII;
1522 const HexagonRegisterInfo &HRI;
1523 MachineRegisterInfo &MRI;
1524 BitTracker &BT;
1526 };
1527
1528
1529
1530 class CopyPropagation : public Transformation {
1531 public:
1532 CopyPropagation(const HexagonRegisterInfo &hri, MachineRegisterInfo &mri)
1533 : Transformation(false), HRI(hri), MRI(mri) {}
1534
1535 bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1536
1537 static bool isCopyReg(unsigned Opc, bool NoConv);
1538
1539 private:
1540 bool propagateRegCopy(MachineInstr &MI);
1541
1542 const HexagonRegisterInfo &HRI;
1543 MachineRegisterInfo &MRI;
1544 };
1545
1546}
1547
1548
1549
1550bool CopyGeneration::findMatch(const BitTracker::RegisterRef &Inp,
1551 BitTracker::RegisterRef &Out, const RegisterSet &AVs) {
1553 return false;
1554 const BitTracker::RegisterCell &InpRC = BT.lookup(Inp.Reg);
1555 auto *FRC = HBS::getFinalVRegClass(Inp, MRI);
1557 if (!HBS::getSubregMask(Inp, B, W, MRI))
1558 return false;
1559
1560 for (Register R = AVs.find_first(); R; R = AVs.find_next(R)) {
1561 if (.has(R) || Forbidden[R])
1562 continue;
1563 const BitTracker::RegisterCell &RC = BT.lookup(R);
1564 unsigned RW = RC.width();
1565 if (W == RW) {
1566 if (FRC != MRI.getRegClass(R))
1567 continue;
1568 if (!HBS::isTransparentCopy(R, Inp, MRI))
1569 continue;
1570 if (!HBS::isEqual(InpRC, B, RC, 0, W))
1571 continue;
1573 Out.Sub = 0;
1574 return true;
1575 }
1576
1577
1578
1579 if (W*2 != RW)
1580 continue;
1581 if (MRI.getRegClass(R) != &Hexagon::DoubleRegsRegClass)
1582 continue;
1583
1584 if (HBS::isEqual(InpRC, B, RC, 0, W))
1585 Out.Sub = Hexagon::isub_lo;
1586 else if (HBS::isEqual(InpRC, B, RC, W, W))
1587 Out.Sub = Hexagon::isub_hi;
1588 else
1589 continue;
1591 if (HBS::isTransparentCopy(Out, Inp, MRI))
1592 return true;
1593 }
1594 return false;
1595}
1596
1597bool CopyGeneration::processBlock(MachineBasicBlock &B,
1600 return false;
1604
1605 for (auto I = B.begin(), E = B.end(); I != E; ++I, AVB.insert(Defs)) {
1606 Defs.clear();
1607 HBS::getInstrDefs(*I, Defs);
1608
1609 unsigned Opc = I->getOpcode();
1610 if (CopyPropagation::isCopyReg(Opc, false) ||
1611 ConstGeneration::isTfrConst(*I))
1612 continue;
1613
1615 auto At = I->isPHI() ? B.getFirstNonPHI() : I;
1616
1617 for (Register R = Defs.find_first(); R; R = Defs.find_next(R)) {
1618 BitTracker::RegisterRef MR;
1619 auto *FRC = HBS::getFinalVRegClass(R, MRI);
1620
1621 if (findMatch(R, MR, AVB)) {
1622 Register NewR = MRI.createVirtualRegister(FRC);
1623 BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
1625 BT.put(BitTracker::RegisterRef(NewR), BT.get(MR));
1626 HBS::replaceReg(R, NewR, MRI);
1627 Forbidden.insert(R);
1628 continue;
1629 }
1630
1631 if (FRC == &Hexagon::DoubleRegsRegClass ||
1632 FRC == &Hexagon::HvxWRRegClass) {
1633
1636 BitTracker::RegisterRef TL = { R, SubLo };
1637 BitTracker::RegisterRef TH = { R, SubHi };
1638 BitTracker::RegisterRef ML, MH;
1639 if (findMatch(TL, ML, AVB) && findMatch(TH, MH, AVB)) {
1640 auto *FRC = HBS::getFinalVRegClass(R, MRI);
1641 Register NewR = MRI.createVirtualRegister(FRC);
1642 BuildMI(B, At, DL, HII.get(TargetOpcode::REG_SEQUENCE), NewR)
1647 BT.put(BitTracker::RegisterRef(NewR), BT.get(R));
1648 HBS::replaceReg(R, NewR, MRI);
1649 Forbidden.insert(R);
1650 }
1651 }
1652 }
1653 }
1654
1656}
1657
1658bool CopyPropagation::isCopyReg(unsigned Opc, bool NoConv) {
1659 switch (Opc) {
1660 case TargetOpcode::COPY:
1661 case TargetOpcode::REG_SEQUENCE:
1662 case Hexagon::A4_combineir:
1663 case Hexagon::A4_combineri:
1664 return true;
1665 case Hexagon::A2_tfr:
1666 case Hexagon::A2_tfrp:
1667 case Hexagon::A2_combinew:
1668 case Hexagon::V6_vcombine:
1669 return NoConv;
1670 default:
1671 break;
1672 }
1673 return false;
1674}
1675
1676bool CopyPropagation::propagateRegCopy(MachineInstr &MI) {
1678 unsigned Opc = MI.getOpcode();
1679 BitTracker::RegisterRef RD = MI.getOperand(0);
1680 assert(MI.getOperand(0).getSubReg() == 0);
1681
1682 switch (Opc) {
1683 case TargetOpcode::COPY:
1684 case Hexagon::A2_tfr:
1685 case Hexagon::A2_tfrp: {
1686 BitTracker::RegisterRef RS = MI.getOperand(1);
1687 if (!HBS::isTransparentCopy(RD, RS, MRI))
1688 break;
1689 if (RS.Sub != 0)
1691 else
1693 break;
1694 }
1695 case TargetOpcode::REG_SEQUENCE: {
1696 BitTracker::RegisterRef SL, SH;
1697 if (HBS::parseRegSequence(MI, SL, SH, MRI)) {
1698 const TargetRegisterClass &RC = *MRI.getRegClass(RD.Reg);
1703 }
1704 break;
1705 }
1706 case Hexagon::A2_combinew:
1707 case Hexagon::V6_vcombine: {
1708 const TargetRegisterClass &RC = *MRI.getRegClass(RD.Reg);
1711 BitTracker::RegisterRef RH = MI.getOperand(1), RL = MI.getOperand(2);
1712 Changed = HBS::replaceSubWithSub(RD.Reg, SubLo, RL.Reg, RL.Sub, MRI);
1714 break;
1715 }
1716 case Hexagon::A4_combineir:
1717 case Hexagon::A4_combineri: {
1718 unsigned SrcX = (Opc == Hexagon::A4_combineir) ? 2 : 1;
1719 unsigned Sub = (Opc == Hexagon::A4_combineir) ? Hexagon::isub_lo
1720 : Hexagon::isub_hi;
1721 BitTracker::RegisterRef RS = MI.getOperand(SrcX);
1723 break;
1724 }
1725 }
1727}
1728
1729bool CopyPropagation::processBlock(MachineBasicBlock &B, const RegisterSet&) {
1730 std::vector<MachineInstr*> Instrs;
1732 Instrs.push_back(&MI);
1733
1735 for (auto *I : Instrs) {
1736 unsigned Opc = I->getOpcode();
1737 if (!CopyPropagation::isCopyReg(Opc, true))
1738 continue;
1739 Changed |= propagateRegCopy(*I);
1740 }
1741
1743}
1744
1745namespace {
1746
1747
1748
1749
1750 class BitSimplification : public Transformation {
1751 public:
1752 BitSimplification(BitTracker &bt, const MachineDominatorTree &mdt,
1753 const HexagonInstrInfo &hii,
1754 const HexagonRegisterInfo &hri, MachineRegisterInfo &mri,
1755 MachineFunction &mf)
1756 : Transformation(true), MDT(mdt), HII(hii), HRI(hri), MRI(mri), BT(bt) {
1757 }
1758
1759 bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1760
1761 private:
1762 struct RegHalf : public BitTracker::RegisterRef {
1763 bool Low;
1764 };
1765
1766 bool matchHalf(unsigned SelfR, const BitTracker::RegisterCell &RC,
1767 unsigned B, RegHalf &RH);
1768 bool validateReg(BitTracker::RegisterRef R, unsigned Opc, unsigned OpNum);
1769
1770 bool matchPackhl(unsigned SelfR, const BitTracker::RegisterCell &RC,
1771 BitTracker::RegisterRef &Rs, BitTracker::RegisterRef &Rt);
1772 unsigned getCombineOpcode(bool HLow, bool LLow);
1773
1774 bool genStoreUpperHalf(MachineInstr *MI);
1775 bool genStoreImmediate(MachineInstr *MI);
1776 bool genPackhl(MachineInstr *MI, BitTracker::RegisterRef RD,
1777 const BitTracker::RegisterCell &RC);
1778 bool genExtractHalf(MachineInstr *MI, BitTracker::RegisterRef RD,
1779 const BitTracker::RegisterCell &RC);
1780 bool genCombineHalf(MachineInstr *MI, BitTracker::RegisterRef RD,
1781 const BitTracker::RegisterCell &RC);
1782 bool genExtractLow(MachineInstr *MI, BitTracker::RegisterRef RD,
1783 const BitTracker::RegisterCell &RC);
1784 bool genBitSplit(MachineInstr *MI, BitTracker::RegisterRef RD,
1785 const BitTracker::RegisterCell &RC, const RegisterSet &AVs);
1786 bool simplifyTstbit(MachineInstr *MI, BitTracker::RegisterRef RD,
1787 const BitTracker::RegisterCell &RC);
1788 bool simplifyExtractLow(MachineInstr *MI, BitTracker::RegisterRef RD,
1789 const BitTracker::RegisterCell &RC, const RegisterSet &AVs);
1790 bool simplifyRCmp0(MachineInstr *MI, BitTracker::RegisterRef RD);
1791
1792
1793
1794 std::vector<MachineInstr*> NewMIs;
1795
1796 const MachineDominatorTree &MDT;
1797 const HexagonInstrInfo &HII;
1798 [[maybe_unused]] const HexagonRegisterInfo &HRI;
1799 MachineRegisterInfo &MRI;
1800 BitTracker &BT;
1801 };
1802
1803}
1804
1805
1806
1807
1808bool BitSimplification::matchHalf(unsigned SelfR,
1809 const BitTracker::RegisterCell &RC, unsigned B, RegHalf &RH) {
1810
1811
1812
1813
1814
1815
1816
1817 bool Low = false;
1819 while (I < B+16 && RC[I].num())
1820 I++;
1822 return false;
1823
1825 unsigned P = RC[I].RefI.Pos;
1827 return false;
1828 unsigned Pos = P - (I-B);
1829
1830 if (Reg == 0 || Reg == SelfR)
1831 return false;
1833 return false;
1835 return false;
1836
1837 const BitTracker::RegisterCell &SC = BT.lookup(Reg);
1838 if (Pos+16 > SC.width())
1839 return false;
1840
1841 for (unsigned i = 0; i < 16; ++i) {
1842 const BitTracker::BitValue &RV = RC[i+B];
1845 return false;
1846 if (RV.RefI.Pos != i+Pos)
1847 return false;
1848 continue;
1849 }
1850 if (RC[i+B] != SC[i+Pos])
1851 return false;
1852 }
1853
1854 unsigned Sub = 0;
1855 switch (Pos) {
1856 case 0:
1857 Sub = Hexagon::isub_lo;
1858 Low = true;
1859 break;
1860 case 16:
1861 Sub = Hexagon::isub_lo;
1862 Low = false;
1863 break;
1864 case 32:
1865 Sub = Hexagon::isub_hi;
1866 Low = true;
1867 break;
1868 case 48:
1869 Sub = Hexagon::isub_hi;
1870 Low = false;
1871 break;
1872 default:
1873 return false;
1874 }
1875
1876 RH.Reg = Reg;
1877 RH.Sub = Sub;
1878 RH.Low = Low;
1879
1880 if (!HBS::getFinalVRegClass(RH, MRI))
1881 RH.Sub = 0;
1882
1883 return true;
1884}
1885
1886bool BitSimplification::validateReg(BitTracker::RegisterRef R, unsigned Opc,
1887 unsigned OpNum) {
1888 auto *OpRC = HII.getRegClass(HII.get(Opc), OpNum);
1889 auto *RRC = HBS::getFinalVRegClass(R, MRI);
1890 return OpRC->hasSubClassEq(RRC);
1891}
1892
1893
1894
1895bool BitSimplification::matchPackhl(unsigned SelfR,
1896 const BitTracker::RegisterCell &RC, BitTracker::RegisterRef &Rs,
1897 BitTracker::RegisterRef &Rt) {
1898 RegHalf L1, H1, L2, H2;
1899
1900 if (!matchHalf(SelfR, RC, 0, L2) || !matchHalf(SelfR, RC, 16, L1))
1901 return false;
1902 if (!matchHalf(SelfR, RC, 32, H2) || !matchHalf(SelfR, RC, 48, H1))
1903 return false;
1904
1905
1906 if (H1.Reg != L1.Reg || H1.Sub != L1.Sub || H1.Low || !L1.Low)
1907 return false;
1908 if (H2.Reg != L2.Reg || H2.Sub != L2.Sub || H2.Low || !L2.Low)
1909 return false;
1910
1911 Rs = H1;
1912 Rt = H2;
1913 return true;
1914}
1915
1916unsigned BitSimplification::getCombineOpcode(bool HLow, bool LLow) {
1917 return HLow ? LLow ? Hexagon::A2_combine_ll
1918 : Hexagon::A2_combine_lh
1919 : LLow ? Hexagon::A2_combine_hl
1920 : Hexagon::A2_combine_hh;
1921}
1922
1923
1924
1925
1926bool BitSimplification::genStoreUpperHalf(MachineInstr *MI) {
1927 unsigned Opc = MI->getOpcode();
1928 if (Opc != Hexagon::S2_storerh_io)
1929 return false;
1930
1931 MachineOperand &ValOp = MI->getOperand(2);
1932 BitTracker::RegisterRef RS = ValOp;
1934 return false;
1935 const BitTracker::RegisterCell &RC = BT.lookup(RS.Reg);
1936 RegHalf H;
1937 unsigned B = (RS.Sub == Hexagon::isub_hi) ? 32 : 0;
1938 if (!matchHalf(0, RC, B, H))
1939 return false;
1940 if (H.Low)
1941 return false;
1942 MI->setDesc(HII.get(Hexagon::S2_storerf_io));
1945 return true;
1946}
1947
1948
1949
1950bool BitSimplification::genStoreImmediate(MachineInstr *MI) {
1951 unsigned Opc = MI->getOpcode();
1952 unsigned Align = 0;
1953 switch (Opc) {
1954 case Hexagon::S2_storeri_io:
1956 [[fallthrough]];
1957 case Hexagon::S2_storerh_io:
1959 [[fallthrough]];
1960 case Hexagon::S2_storerb_io:
1961 break;
1962 default:
1963 return false;
1964 }
1965
1966
1967 if (->getOperand(0).isReg())
1968 return false;
1969 MachineOperand &OffOp = MI->getOperand(1);
1970 if (!OffOp.isImm())
1971 return false;
1972
1974
1975 if ((6+Align, Off) || (Off & ((1<<Align)-1)))
1976 return false;
1977
1978 BitTracker::RegisterRef RS = MI->getOperand(2);
1980 return false;
1981 const BitTracker::RegisterCell &RC = BT.lookup(RS.Reg);
1982 uint64_t U;
1983 if (!HBS::getConst(RC, 0, RC.width(), U))
1984 return false;
1985
1986
1987 int V;
1988 switch (Opc) {
1989 case Hexagon::S2_storerb_io:
1990 V = int8_t(U);
1991 break;
1992 case Hexagon::S2_storerh_io:
1993 V = int16_t(U);
1994 break;
1995 case Hexagon::S2_storeri_io:
1996 V = int32_t(U);
1997 break;
1998 default:
1999
2000
2002 }
2004 return false;
2005
2006 MI->removeOperand(2);
2007 switch (Opc) {
2008 case Hexagon::S2_storerb_io:
2009 MI->setDesc(HII.get(Hexagon::S4_storeirb_io));
2010 break;
2011 case Hexagon::S2_storerh_io:
2012 MI->setDesc(HII.get(Hexagon::S4_storeirh_io));
2013 break;
2014 case Hexagon::S2_storeri_io:
2015 MI->setDesc(HII.get(Hexagon::S4_storeiri_io));
2016 break;
2017 }
2019 return true;
2020}
2021
2022
2023
2024
2025
2026bool BitSimplification::genPackhl(MachineInstr *MI,
2027 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2028 unsigned Opc = MI->getOpcode();
2029 if (Opc == Hexagon::S2_packhl)
2030 return false;
2031 BitTracker::RegisterRef Rs, Rt;
2032 if (!matchPackhl(RD.Reg, RC, Rs, Rt))
2033 return false;
2034 if (!validateReg(Rs, Hexagon::S2_packhl, 1) ||
2035 !validateReg(Rt, Hexagon::S2_packhl, 2))
2036 return false;
2037
2038 MachineBasicBlock &B = *MI->getParent();
2039 Register NewR = MRI.createVirtualRegister(&Hexagon::DoubleRegsRegClass);
2041 auto At = MI->isPHI() ? B.getFirstNonPHI()
2043 BuildMI(B, At, DL, HII.get(Hexagon::S2_packhl), NewR)
2046 HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
2047 BT.put(BitTracker::RegisterRef(NewR), RC);
2048 return true;
2049}
2050
2051
2052
2053bool BitSimplification::genExtractHalf(MachineInstr *MI,
2054 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2055 RegHalf L;
2056
2057 if (!matchHalf(RD.Reg, RC, 0, L) || !HBS::isZero(RC, 16, 16))
2058 return false;
2059
2060 unsigned Opc = MI->getOpcode();
2061 MachineBasicBlock &B = *MI->getParent();
2063
2064
2065
2066 unsigned NewR = 0;
2067 auto At = MI->isPHI() ? B.getFirstNonPHI()
2069 if (L.Low && Opc != Hexagon::A2_zxth) {
2070 if (validateReg(L, Hexagon::A2_zxth, 1)) {
2071 NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2072 BuildMI(B, At, DL, HII.get(Hexagon::A2_zxth), NewR)
2074 }
2075 } else if (.Low && Opc != Hexagon::S2_lsr_i_r) {
2076 if (validateReg(L, Hexagon::S2_lsr_i_r, 1)) {
2077 NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2078 BuildMI(B, MI, DL, HII.get(Hexagon::S2_lsr_i_r), NewR)
2081 }
2082 }
2083 if (NewR == 0)
2084 return false;
2085 HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
2086 BT.put(BitTracker::RegisterRef(NewR), RC);
2087 return true;
2088}
2089
2090
2091
2092bool BitSimplification::genCombineHalf(MachineInstr *MI,
2093 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2095
2096 if (!matchHalf(RD.Reg, RC, 0, L) || !matchHalf(RD.Reg, RC, 16, H))
2097 return false;
2098
2099 if (L.Reg == H.Reg && L.Sub == H.Sub && .Low && L.Low)
2100 return false;
2101
2102 unsigned Opc = MI->getOpcode();
2103 unsigned COpc = getCombineOpcode(H.Low, L.Low);
2104 if (COpc == Opc)
2105 return false;
2106 if (!validateReg(H, COpc, 1) || !validateReg(L, COpc, 2))
2107 return false;
2108
2109 MachineBasicBlock &B = *MI->getParent();
2111 Register NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2112 auto At = MI->isPHI() ? B.getFirstNonPHI()
2114 BuildMI(B, At, DL, HII.get(COpc), NewR)
2117 HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
2118 BT.put(BitTracker::RegisterRef(NewR), RC);
2119 return true;
2120}
2121
2122
2123
2124bool BitSimplification::genExtractLow(MachineInstr *MI,
2125 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2126 unsigned Opc = MI->getOpcode();
2127 switch (Opc) {
2128 case Hexagon::A2_zxtb:
2129 case Hexagon::A2_zxth:
2130 case Hexagon::S2_extractu:
2131 return false;
2132 }
2133 if (Opc == Hexagon::A2_andir && MI->getOperand(2).isImm()) {
2134 int32_t Imm = MI->getOperand(2).getImm();
2136 return false;
2137 }
2138
2139 if (MI->hasUnmodeledSideEffects() || MI->isInlineAsm())
2140 return false;
2142 while (W > 0 && RC[W-1].is(0))
2143 W--;
2144 if (W == 0 || W == RC.width())
2145 return false;
2146 unsigned NewOpc = (W == 8) ? Hexagon::A2_zxtb
2147 : (W == 16) ? Hexagon::A2_zxth
2148 : (W < 10) ? Hexagon::A2_andir
2149 : Hexagon::S2_extractu;
2150 MachineBasicBlock &B = *MI->getParent();
2152
2153 for (auto &Op : MI->uses()) {
2154 if (!Op.isReg())
2155 continue;
2156 BitTracker::RegisterRef RS = Op;
2157 if (!BT.has(RS.Reg))
2158 continue;
2159 const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
2160 unsigned BN, BW;
2161 if (!HBS::getSubregMask(RS, BN, BW, MRI))
2162 continue;
2163 if (BW < W || !HBS::isEqual(RC, 0, SC, BN, W))
2164 continue;
2165 if (!validateReg(RS, NewOpc, 1))
2166 continue;
2167
2168 Register NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2169 auto At = MI->isPHI() ? B.getFirstNonPHI()
2170 : MachineBasicBlock::iterator(MI);
2171 auto MIB = BuildMI(B, At, DL, HII.get(NewOpc), NewR)
2172 .addReg(RS.Reg, 0, RS.Sub);
2173 if (NewOpc == Hexagon::A2_andir)
2174 MIB.addImm((1 << W) - 1);
2175 else if (NewOpc == Hexagon::S2_extractu)
2176 MIB.addImm(W).addImm(0);
2177 HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
2178 BT.put(BitTracker::RegisterRef(NewR), RC);
2179 return true;
2180 }
2181 return false;
2182}
2183
2184bool BitSimplification::genBitSplit(MachineInstr *MI,
2185 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC,
2188 return false;
2191 return false;
2192 }
2193
2194 unsigned Opc = MI->getOpcode();
2195 switch (Opc) {
2196 case Hexagon::A4_bitsplit:
2197 case Hexagon::A4_bitspliti:
2198 return false;
2199 }
2200
2202 if (W != 32)
2203 return false;
2204
2205 auto ctlz = [] (const BitTracker::RegisterCell &C) -> unsigned {
2207 while (Z > 0 && C[Z-1].is(0))
2208 --Z;
2210 };
2211
2212
2213 unsigned Z = ctlz(RC);
2214 if (Z == 0 || Z == W)
2215 return false;
2216
2217
2218
2219 const BitTracker::BitValue &B0 = RC[0];
2221 return false;
2222
2223 unsigned SrcR = B0.RefI.Reg;
2224 unsigned SrcSR = 0;
2225 unsigned Pos = B0.RefI.Pos;
2226
2227
2228 for (unsigned i = 1; i < W-Z; ++i) {
2229 const BitTracker::BitValue &V = RC[i];
2231 return false;
2232 if (V.RefI.Reg != SrcR || V.RefI.Pos != Pos+i)
2233 return false;
2234 }
2235
2236
2237 for (unsigned S = AVs.find_first(); S; S = AVs.find_next(S)) {
2238
2239
2240 unsigned SRC = MRI.getRegClass(S)->getID();
2241 if (SRC != Hexagon::IntRegsRegClassID &&
2242 SRC != Hexagon::DoubleRegsRegClassID)
2243 continue;
2245 continue;
2246 const BitTracker::RegisterCell &SC = BT.lookup(S);
2247 if (SC.width() != W || ctlz(SC) != W-Z)
2248 continue;
2249
2250 const BitTracker::BitValue &S0 = SC[0];
2252 continue;
2254
2255 if (Pos <= P && (Pos + W-Z) != P)
2256 continue;
2257 if (P < Pos && (P + Z) != Pos)
2258 continue;
2259
2260 if (std::min(P, Pos) != 0 && std::min(P, Pos) != 32)
2261 continue;
2262
2263 unsigned I;
2264 for (I = 1; I < Z; ++I) {
2265 const BitTracker::BitValue &V = SC[I];
2267 break;
2268 if (V.RefI.Reg != SrcR || V.RefI.Pos != P+I)
2269 break;
2270 }
2271 if (I != Z)
2272 continue;
2273
2274
2277 MachineInstr *DefS = MRI.getVRegDef(S);
2278 assert(DefS != nullptr);
2280 MachineBasicBlock &B = *DefS->getParent();
2281 auto At = DefS->isPHI() ? B.getFirstNonPHI()
2283 if (MRI.getRegClass(SrcR)->getID() == Hexagon::DoubleRegsRegClassID)
2284 SrcSR = (std::min(Pos, P) == 32) ? Hexagon::isub_hi : Hexagon::isub_lo;
2285 if (!validateReg({SrcR,SrcSR}, Hexagon::A4_bitspliti, 1))
2286 continue;
2287 unsigned ImmOp = Pos <= P ? W-Z : Z;
2288
2289
2290 unsigned NewR = 0;
2291 for (MachineInstr *In : NewMIs) {
2292 if (In->getOpcode() != Hexagon::A4_bitspliti)
2293 continue;
2294 MachineOperand &Op1 = In->getOperand(1);
2296 continue;
2297 if (In->getOperand(2).getImm() != ImmOp)
2298 continue;
2299
2300 MachineOperand &Op0 = In->getOperand(0);
2301 MachineInstr *DefI = MRI.getVRegDef(Op0.getReg());
2302 assert(DefI != nullptr);
2304 continue;
2305
2306
2308 NewR = Op0.getReg();
2309 break;
2310 }
2311 if (!NewR) {
2312 NewR = MRI.createVirtualRegister(&Hexagon::DoubleRegsRegClass);
2313 auto NewBS = BuildMI(B, At, DL, HII.get(Hexagon::A4_bitspliti), NewR)
2314 .addReg(SrcR, 0, SrcSR)
2316 NewMIs.push_back(NewBS);
2317 }
2318 if (Pos <= P) {
2319 HBS::replaceRegWithSub(RD.Reg, NewR, Hexagon::isub_lo, MRI);
2320 HBS::replaceRegWithSub(S, NewR, Hexagon::isub_hi, MRI);
2321 } else {
2322 HBS::replaceRegWithSub(S, NewR, Hexagon::isub_lo, MRI);
2323 HBS::replaceRegWithSub(RD.Reg, NewR, Hexagon::isub_hi, MRI);
2324 }
2325 return true;
2326 }
2327
2328 return false;
2329}
2330
2331
2332
2333
2334
2335
2336
2337bool BitSimplification::simplifyTstbit(MachineInstr *MI,
2338 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2339 unsigned Opc = MI->getOpcode();
2340 if (Opc != Hexagon::S2_tstbit_i)
2341 return false;
2342
2343 unsigned BN = MI->getOperand(2).getImm();
2344 BitTracker::RegisterRef RS = MI->getOperand(1);
2347 if (.has(RS.Reg) || !HBS::getSubregMask(RS, F, W, MRI))
2348 return false;
2349 MachineBasicBlock &B = *MI->getParent();
2350 auto At = MI->isPHI() ? B.getFirstNonPHI()
2352
2353 const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
2354 const BitTracker::BitValue &V = SC[F+BN];
2356 const TargetRegisterClass *TC = MRI.getRegClass(V.RefI.Reg);
2357
2358
2359
2360 unsigned P = std::numeric_limits::max();
2361 BitTracker::RegisterRef RR(V.RefI.Reg, 0);
2362 if (TC == &Hexagon::DoubleRegsRegClass) {
2364 RR.Sub = Hexagon::isub_lo;
2365 if (P >= 32) {
2366 P -= 32;
2367 RR.Sub = Hexagon::isub_hi;
2368 }
2369 } else if (TC == &Hexagon::IntRegsRegClass) {
2371 }
2372 if (P != std::numeric_limits::max()) {
2373 Register NewR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
2374 BuildMI(B, At, DL, HII.get(Hexagon::S2_tstbit_i), NewR)
2377 HBS::replaceReg(RD.Reg, NewR, MRI);
2379 return true;
2380 }
2381 } else if (V.is(0) || V.is(1)) {
2382 Register NewR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
2383 unsigned NewOpc = V.is(0) ? Hexagon::PS_false : Hexagon::PS_true;
2384 BuildMI(B, At, DL, HII.get(NewOpc), NewR);
2385 HBS::replaceReg(RD.Reg, NewR, MRI);
2386 return true;
2387 }
2388
2389 return false;
2390}
2391
2392
2393
2394
2395
2396
2397bool BitSimplification::simplifyExtractLow(MachineInstr *MI,
2398 BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC,
2401 return false;
2402 if (MaxExtract.getNumOccurrences()) {
2404 return false;
2406 }
2407
2409 unsigned RW = W;
2410 unsigned Len;
2412
2413
2414
2415
2416 const TargetRegisterClass *FRC = HBS::getFinalVRegClass(RD, MRI);
2417 if (FRC != &Hexagon::IntRegsRegClass && FRC != &Hexagon::DoubleRegsRegClass)
2418 return false;
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431 const BitTracker::BitValue &TopV = RC[W-1];
2432
2433
2434
2435
2437 for (unsigned I = 0; I != W; ++I) {
2438 const BitTracker::BitValue &V = RC[I];
2440 return false;
2442 }
2443 if (IsConst)
2444 return false;
2445
2446 if (TopV.is(0) || TopV.is(1)) {
2447 bool S = TopV.is(1);
2448 for (--W; W > 0 && RC[W-1].is(S); --W)
2449 ;
2452
2455 } else {
2456
2459 return false;
2460 for (--W; W > 0 && RC[W-1] == TopV; --W)
2461 ;
2462
2463
2466 }
2467
2468
2469 if (Len == RW)
2470 return false;
2471
2474 << ", MI: " << *MI;
2475 dbgs() << "Cell: " << RC << '\n';
2476 dbgs() << "Expected bitfield size: " << Len << " bits, "
2477 << (Signed ? "sign" : "zero") << "-extended\n";
2478 });
2479
2481
2482 for (unsigned R = AVs.find_first(); R != 0; R = AVs.find_next(R)) {
2484 continue;
2485 const BitTracker::RegisterCell &SC = BT.lookup(R);
2486 unsigned SW = SC.width();
2487
2488
2489
2490
2491
2492 if (SW < RW || (SW % RW) != 0)
2493 continue;
2494
2495
2496
2497
2498 unsigned Off = 0;
2499 while (Off <= SW-Len) {
2500 unsigned OE = (Off+Len)/RW;
2501 if (OE != Off/RW) {
2502
2503
2504
2505
2506
2507
2508 Off = OE*RW;
2509 continue;
2510 }
2511 if (HBS::isEqual(RC, 0, SC, Off, Len))
2512 break;
2514 }
2515
2516 if (Off > SW-Len)
2517 continue;
2518
2519
2520 unsigned ExtOpc = 0;
2521 if (Off == 0) {
2522 if (Len == 8)
2523 ExtOpc = Signed ? Hexagon::A2_sxtb : Hexagon::A2_zxtb;
2524 else if (Len == 16)
2525 ExtOpc = Signed ? Hexagon::A2_sxth : Hexagon::A2_zxth;
2526 else if (Len < 10 && )
2527 ExtOpc = Hexagon::A2_andir;
2528 }
2529 if (ExtOpc == 0) {
2530 ExtOpc =
2531 Signed ? (RW == 32 ? Hexagon::S4_extract : Hexagon::S4_extractp)
2532 : (RW == 32 ? Hexagon::S2_extractu : Hexagon::S2_extractup);
2533 }
2534 unsigned SR = 0;
2535
2536 if (RW != SW && RW*2 != SW)
2537 continue;
2538 if (RW != SW)
2539 SR = (Off/RW == 0) ? Hexagon::isub_lo : Hexagon::isub_hi;
2541
2542 if (!validateReg({R,SR}, ExtOpc, 1))
2543 continue;
2544
2545
2546 if (MI->getOpcode() == ExtOpc) {
2547
2548 const MachineOperand &SrcOp = MI->getOperand(1);
2549 if (SrcOp.getReg() == R)
2550 continue;
2551 }
2552
2554 MachineBasicBlock &B = *MI->getParent();
2555 Register NewR = MRI.createVirtualRegister(FRC);
2556 auto At = MI->isPHI() ? B.getFirstNonPHI()
2558 auto MIB = BuildMI(B, At, DL, HII.get(ExtOpc), NewR)
2560 switch (ExtOpc) {
2561 case Hexagon::A2_sxtb:
2562 case Hexagon::A2_zxtb:
2563 case Hexagon::A2_sxth:
2564 case Hexagon::A2_zxth:
2565 break;
2566 case Hexagon::A2_andir:
2567 MIB.addImm((1u << Len) - 1);
2568 break;
2569 case Hexagon::S4_extract:
2570 case Hexagon::S2_extractu:
2571 case Hexagon::S4_extractp:
2572 case Hexagon::S2_extractup:
2573 MIB.addImm(Len)
2574 .addImm(Off);
2575 break;
2576 default:
2578 }
2579
2580 HBS::replaceReg(RD.Reg, NewR, MRI);
2581 BT.put(BitTracker::RegisterRef(NewR), RC);
2583 break;
2584 }
2585
2587}
2588
2589bool BitSimplification::simplifyRCmp0(MachineInstr *MI,
2590 BitTracker::RegisterRef RD) {
2591 unsigned Opc = MI->getOpcode();
2592 if (Opc != Hexagon::A4_rcmpeqi && Opc != Hexagon::A4_rcmpneqi)
2593 return false;
2594 MachineOperand &CmpOp = MI->getOperand(2);
2595 if (!CmpOp.isImm() || CmpOp.getImm() != 0)
2596 return false;
2597
2598 const TargetRegisterClass *FRC = HBS::getFinalVRegClass(RD, MRI);
2599 if (FRC != &Hexagon::IntRegsRegClass && FRC != &Hexagon::DoubleRegsRegClass)
2600 return false;
2602
2603 MachineBasicBlock &B = *MI->getParent();
2605 auto At = MI->isPHI() ? B.getFirstNonPHI()
2607 bool KnownZ = true;
2608 bool KnownNZ = false;
2609
2610 BitTracker::RegisterRef SR = MI->getOperand(1);
2612 return false;
2613 const BitTracker::RegisterCell &SC = BT.lookup(SR.Reg);
2615 if (!HBS::getSubregMask(SR, F, W, MRI))
2616 return false;
2617
2618 for (uint16_t I = F; I != F+W; ++I) {
2619 const BitTracker::BitValue &V = SC[I];
2620 if (.is(0))
2621 KnownZ = false;
2622 if (V.is(1))
2623 KnownNZ = true;
2624 }
2625
2626 auto ReplaceWithConst = [&](int C) {
2627 Register NewR = MRI.createVirtualRegister(FRC);
2628 BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrsi), NewR)
2630 HBS::replaceReg(RD.Reg, NewR, MRI);
2631 BitTracker::RegisterCell NewRC(W);
2632 for (uint16_t I = 0; I != W; ++I) {
2633 NewRC[I] = BitTracker::BitValue(C & 1);
2635 }
2636 BT.put(BitTracker::RegisterRef(NewR), NewRC);
2637 return true;
2638 };
2639
2640 auto IsNonZero = [] (const MachineOperand &Op) {
2641 if (Op.isGlobal() || Op.isBlockAddress())
2642 return true;
2643 if (Op.isImm())
2644 return Op.getImm() != 0;
2645 if (Op.isCImm())
2646 return .getCImm()->isZero();
2647 if (Op.isFPImm())
2648 return .getFPImm()->isZero();
2649 return false;
2650 };
2651
2652 auto IsZero = [] (const MachineOperand &Op) {
2653 if (Op.isGlobal() || Op.isBlockAddress())
2654 return false;
2655 if (Op.isImm())
2656 return Op.getImm() == 0;
2657 if (Op.isCImm())
2658 return Op.getCImm()->isZero();
2659 if (Op.isFPImm())
2660 return Op.getFPImm()->isZero();
2661 return false;
2662 };
2663
2664
2665
2666 if (KnownZ || KnownNZ) {
2667 assert(KnownZ != KnownNZ && "Register cannot be both 0 and non-0");
2668 return ReplaceWithConst(KnownZ == (Opc == Hexagon::A4_rcmpeqi));
2669 }
2670
2671
2672
2673 MachineInstr *InpDef = MRI.getVRegDef(SR.Reg);
2674 if (!InpDef)
2675 return false;
2676 if (SR.Sub == 0 && InpDef->getOpcode() == Hexagon::C2_muxii) {
2677 MachineOperand &Src1 = InpDef->getOperand(2);
2678 MachineOperand &Src2 = InpDef->getOperand(3);
2679
2680 bool KnownNZ1 = IsNonZero(Src1), KnownNZ2 = IsNonZero(Src2);
2681 if (KnownNZ1 && KnownNZ2)
2682 return ReplaceWithConst(Opc == Hexagon::A4_rcmpneqi);
2683
2684 bool KnownZ1 = IsZero(Src1), KnownZ2 = IsZero(Src2);
2685 if (KnownZ1 && KnownZ2)
2686 return ReplaceWithConst(Opc == Hexagon::A4_rcmpeqi);
2687
2688
2689
2690
2691 if ((KnownZ1 || KnownNZ1) && (KnownZ2 || KnownNZ2)) {
2692 Register NewR = MRI.createVirtualRegister(FRC);
2693 BuildMI(B, At, DL, HII.get(Hexagon::C2_muxii), NewR)
2695 .addImm(KnownZ1 == (Opc == Hexagon::A4_rcmpeqi))
2696 .addImm(KnownZ2 == (Opc == Hexagon::A4_rcmpeqi));
2697 HBS::replaceReg(RD.Reg, NewR, MRI);
2698
2699 BitTracker::RegisterCell NewRC(W);
2702 BT.put(BitTracker::RegisterRef(NewR), NewRC);
2703 return true;
2704 }
2705 }
2706
2707 return false;
2708}
2709
2710bool BitSimplification::processBlock(MachineBasicBlock &B,
2713 return false;
2717
2718 for (auto I = B.begin(), E = B.end(); I != E; ++I, AVB.insert(Defs)) {
2720 Defs.clear();
2721 HBS::getInstrDefs(*MI, Defs);
2722
2723 unsigned Opc = MI->getOpcode();
2724 if (Opc == TargetOpcode::COPY || Opc == TargetOpcode::REG_SEQUENCE)
2725 continue;
2726
2727 if (MI->mayStore()) {
2728 bool T = genStoreUpperHalf(MI);
2729 T = T || genStoreImmediate(MI);
2731 continue;
2732 }
2733
2734 if (Defs.count() != 1)
2735 continue;
2736 const MachineOperand &Op0 = MI->getOperand(0);
2738 continue;
2739 BitTracker::RegisterRef RD = Op0;
2741 continue;
2742 const TargetRegisterClass *FRC = HBS::getFinalVRegClass(RD, MRI);
2743 const BitTracker::RegisterCell &RC = BT.lookup(RD.Reg);
2744
2745 if (FRC->getID() == Hexagon::DoubleRegsRegClassID) {
2746 bool T = genPackhl(MI, RD, RC);
2747 T = T || simplifyExtractLow(MI, RD, RC, AVB);
2749 continue;
2750 }
2751
2752 if (FRC->getID() == Hexagon::IntRegsRegClassID) {
2753 bool T = genBitSplit(MI, RD, RC, AVB);
2754 T = T || simplifyExtractLow(MI, RD, RC, AVB);
2755 T = T || genExtractHalf(MI, RD, RC);
2756 T = T || genCombineHalf(MI, RD, RC);
2757 T = T || genExtractLow(MI, RD, RC);
2758 T = T || simplifyRCmp0(MI, RD);
2760 continue;
2761 }
2762
2763 if (FRC->getID() == Hexagon::PredRegsRegClassID) {
2764 bool T = simplifyTstbit(MI, RD, RC);
2766 continue;
2767 }
2768 }
2770}
2771
2772bool HexagonBitSimplify::runOnMachineFunction(MachineFunction &MF) {
2774 return false;
2775
2776 auto &HST = MF.getSubtarget();
2778 auto &HII = *HST.getInstrInfo();
2779
2780 MDT = &getAnalysis().getDomTree();
2783
2784 Changed = DeadCodeElimination(MF, *MDT).run();
2785
2786 const HexagonEvaluator HE(HRI, MRI, HII, MF);
2787 BitTracker BT(HE, MF);
2790
2791 MachineBasicBlock &Entry = MF.front();
2792
2793 RegisterSet AIG;
2794 ConstGeneration ImmG(BT, HII, MRI);
2795 Changed |= visitBlock(Entry, ImmG, AIG);
2796
2797 RegisterSet ARE;
2798 RedundantInstrElimination RIE(BT, HII, HRI, MRI);
2799 bool Ried = visitBlock(Entry, RIE, ARE);
2800 if (Ried) {
2803 }
2804
2805 RegisterSet ACG;
2806 CopyGeneration CopyG(BT, HII, HRI, MRI);
2807 Changed |= visitBlock(Entry, CopyG, ACG);
2808
2809 RegisterSet ACP;
2810 CopyPropagation CopyP(HRI, MRI);
2811 Changed |= visitBlock(Entry, CopyP, ACP);
2812
2813 Changed = DeadCodeElimination(MF, *MDT).run() || Changed;
2814
2817 BitSimplification BitS(BT, *MDT, HII, HRI, MRI, MF);
2818 Changed |= visitBlock(Entry, BitS, ABS);
2819
2820 Changed = DeadCodeElimination(MF, *MDT).run() || Changed;
2821
2823 for (auto &B : MF)
2825 I.clearKillInfo();
2826 DeadCodeElimination(MF, *MDT).run();
2827 }
2829}
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893namespace {
2894
2895 class HexagonLoopRescheduling : public MachineFunctionPass {
2896 public:
2897 static char ID;
2898
2899 HexagonLoopRescheduling() : MachineFunctionPass(ID) {}
2900
2901 bool runOnMachineFunction(MachineFunction &MF) override;
2902
2903 private:
2904 const HexagonInstrInfo *HII = nullptr;
2905 const HexagonRegisterInfo *HRI = nullptr;
2906 MachineRegisterInfo *MRI = nullptr;
2907 BitTracker *BTP = nullptr;
2908
2909 struct LoopCand {
2910 LoopCand(MachineBasicBlock *lb, MachineBasicBlock *pb,
2911 MachineBasicBlock *eb) : LB(lb), PB(pb), EB(eb) {}
2912
2913 MachineBasicBlock *LB, *PB, *EB;
2914 };
2915 using InstrList = std::vector<MachineInstr *>;
2916 struct InstrGroup {
2917 BitTracker::RegisterRef Inp, Out;
2919 };
2920 struct PhiInfo {
2921 PhiInfo(MachineInstr &P, MachineBasicBlock &B);
2922
2923 unsigned DefR;
2924 BitTracker::RegisterRef LR, PR;
2925 MachineBasicBlock *LB, *PB;
2926 };
2927
2928 static unsigned getDefReg(const MachineInstr *MI);
2930 bool isBitShuffle(const MachineInstr *MI, unsigned DefR) const;
2931 bool isStoreInput(const MachineInstr *MI, unsigned DefR) const;
2932 bool isShuffleOf(unsigned OutR, unsigned InpR) const;
2933 bool isSameShuffle(unsigned OutR1, unsigned InpR1, unsigned OutR2,
2934 unsigned &InpR2) const;
2935 void moveGroup(InstrGroup &G, MachineBasicBlock &LB, MachineBasicBlock &PB,
2937 bool processLoop(LoopCand &C);
2938 };
2939
2940}
2941
2942char HexagonLoopRescheduling::ID = 0;
2943
2945 "Hexagon Loop Rescheduling", false, false)
2946
2949 DefR = HexagonLoopRescheduling::getDefReg(&P);
2950 LB = &B;
2951 PB = nullptr;
2952 for (unsigned i = 1, n = P.getNumOperands(); i < n; i += 2) {
2954 if (OpB.getMBB() == &B) {
2955 LR = P.getOperand(i);
2956 continue;
2957 }
2959 PR = P.getOperand(i);
2960 }
2961}
2962
2963unsigned HexagonLoopRescheduling::getDefReg(const MachineInstr *MI) {
2965 HBS::getInstrDefs(*MI, Defs);
2966 if (Defs.count() != 1)
2967 return 0;
2968 return Defs.find_first();
2969}
2970
2971bool HexagonLoopRescheduling::isConst(unsigned Reg) const {
2973 return false;
2974 const BitTracker::RegisterCell &RC = BTP->lookup(Reg);
2975 for (unsigned i = 0, w = RC.width(); i < w; ++i) {
2976 const BitTracker::BitValue &V = RC[i];
2977 if (.is(0) &&
.is(1))
2978 return false;
2979 }
2980 return true;
2981}
2982
2983bool HexagonLoopRescheduling::isBitShuffle(const MachineInstr *MI,
2984 unsigned DefR) const {
2985 unsigned Opc = MI->getOpcode();
2986 switch (Opc) {
2987 case TargetOpcode::COPY:
2988 case Hexagon::S2_lsr_i_r:
2989 case Hexagon::S2_asr_i_r:
2990 case Hexagon::S2_asl_i_r:
2991 case Hexagon::S2_lsr_i_p:
2992 case Hexagon::S2_asr_i_p:
2993 case Hexagon::S2_asl_i_p:
2994 case Hexagon::S2_insert:
2995 case Hexagon::A2_or:
2996 case Hexagon::A2_orp:
2997 case Hexagon::A2_and:
2998 case Hexagon::A2_andp:
2999 case Hexagon::A2_combinew:
3000 case Hexagon::A4_combineri:
3001 case Hexagon::A4_combineir:
3002 case Hexagon::A2_combineii:
3003 case Hexagon::A4_combineii:
3004 case Hexagon::A2_combine_ll:
3005 case Hexagon::A2_combine_lh:
3006 case Hexagon::A2_combine_hl:
3007 case Hexagon::A2_combine_hh:
3008 return true;
3009 }
3010 return false;
3011}
3012
3013bool HexagonLoopRescheduling::isStoreInput(const MachineInstr *MI,
3014 unsigned InpR) const {
3015 for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) {
3016 const MachineOperand &Op = MI->getOperand(i);
3017 if (.isReg())
3018 continue;
3019 if (Op.getReg() == InpR)
3020 return i == n-1;
3021 }
3022 return false;
3023}
3024
3025bool HexagonLoopRescheduling::isShuffleOf(unsigned OutR, unsigned InpR) const {
3026 if (!BTP->has(OutR) || !BTP->has(InpR))
3027 return false;
3028 const BitTracker::RegisterCell &OutC = BTP->lookup(OutR);
3029 for (unsigned i = 0, w = OutC.width(); i < w; ++i) {
3030 const BitTracker::BitValue &V = OutC[i];
3032 continue;
3033 if (V.RefI.Reg != InpR)
3034 return false;
3035 }
3036 return true;
3037}
3038
3039bool HexagonLoopRescheduling::isSameShuffle(unsigned OutR1, unsigned InpR1,
3040 unsigned OutR2, unsigned &InpR2) const {
3041 if (!BTP->has(OutR1) || !BTP->has(InpR1) || !BTP->has(OutR2))
3042 return false;
3043 const BitTracker::RegisterCell &OutC1 = BTP->lookup(OutR1);
3044 const BitTracker::RegisterCell &OutC2 = BTP->lookup(OutR2);
3045 unsigned W = OutC1.width();
3046 unsigned MatchR = 0;
3047 if (W != OutC2.width())
3048 return false;
3049 for (unsigned i = 0; i < W; ++i) {
3050 const BitTracker::BitValue &V1 = OutC1[i], &V2 = OutC2[i];
3052 return false;
3054 continue;
3055 if (V1.RefI.Pos != V2.RefI.Pos)
3056 return false;
3057 if (V1.RefI.Reg != InpR1)
3058 return false;
3059 if (V2.RefI.Reg == 0 || V2.RefI.Reg == OutR2)
3060 return false;
3061 if (!MatchR)
3062 MatchR = V2.RefI.Reg;
3063 else if (V2.RefI.Reg != MatchR)
3064 return false;
3065 }
3066 InpR2 = MatchR;
3067 return true;
3068}
3069
3070void HexagonLoopRescheduling::moveGroup(InstrGroup &G, MachineBasicBlock &LB,
3072 unsigned NewPredR) {
3073 DenseMap<unsigned,unsigned> RegMap;
3074
3075 const TargetRegisterClass *PhiRC = MRI->getRegClass(NewPredR);
3076 Register PhiR = MRI->createVirtualRegister(PhiRC);
3077 BuildMI(LB, At, At->getDebugLoc(), HII->get(TargetOpcode::PHI), PhiR)
3082 RegMap.insert(std::make_pair(G.Inp.Reg, PhiR));
3083
3084 for (const MachineInstr *SI : llvm::reverse(G.Ins)) {
3085 unsigned DR = getDefReg(SI);
3086 const TargetRegisterClass *RC = MRI->getRegClass(DR);
3087 Register NewDR = MRI->createVirtualRegister(RC);
3089
3090 auto MIB = BuildMI(LB, At, DL, HII->get(SI->getOpcode()), NewDR);
3091 for (const MachineOperand &Op : SI->operands()) {
3092 if (.isReg()) {
3093 MIB.add(Op);
3094 continue;
3095 }
3096 if (.isUse())
3097 continue;
3098 unsigned UseR = RegMap[Op.getReg()];
3099 MIB.addReg(UseR, 0, Op.getSubReg());
3100 }
3101 RegMap.insert(std::make_pair(DR, NewDR));
3102 }
3103
3104 HBS::replaceReg(OldPhiR, RegMap[G.Out.Reg], *MRI);
3105}
3106
3107bool HexagonLoopRescheduling::processLoop(LoopCand &C) {
3109 << "\n");
3110 std::vector Phis;
3112 if (.isPHI())
3113 break;
3114 unsigned PR = getDefReg(&I);
3116 continue;
3117 bool BadUse = false, GoodUse = false;
3118 for (const MachineOperand &MO : MRI->use_operands(PR)) {
3119 const MachineInstr *UseI = MO.getParent();
3121 BadUse = true;
3122 break;
3123 }
3124 if (isBitShuffle(UseI, PR) || isStoreInput(UseI, PR))
3125 GoodUse = true;
3126 }
3127 if (BadUse || !GoodUse)
3128 continue;
3129
3130 Phis.push_back(PhiInfo(I, *C.LB));
3131 }
3132
3134 dbgs() << "Phis: {";
3135 for (auto &I : Phis) {
3136 dbgs() << ' ' << printReg(I.DefR, HRI) << "=phi("
3137 << printReg(I.PR.Reg, HRI, I.PR.Sub) << ":b" << I.PB->getNumber()
3138 << ',' << printReg(I.LR.Reg, HRI, I.LR.Sub) << ":b"
3139 << I.LB->getNumber() << ')';
3140 }
3141 dbgs() << " }\n";
3142 });
3143
3144 if (Phis.empty())
3145 return false;
3146
3148 InstrList ShufIns;
3149
3150
3151
3152
3153
3155 if (MI.isTerminator())
3156 continue;
3157 if (MI.isPHI())
3158 break;
3159
3161 HBS::getInstrDefs(MI, Defs);
3162 if (Defs.count() != 1)
3163 continue;
3164 Register DefR = Defs.find_first();
3166 continue;
3167 if (!isBitShuffle(&MI, DefR))
3168 continue;
3169
3170 bool BadUse = false;
3171 for (auto UI = MRI->use_begin(DefR), UE = MRI->use_end(); UI != UE; ++UI) {
3172 MachineInstr *UseI = UI->getParent();
3174 if (UseI->isPHI()) {
3175
3176
3177 unsigned Idx = UI.getOperandNo();
3179 BadUse = true;
3180 } else {
3182 BadUse = true;
3183 }
3184 } else {
3185
3186
3187 if (C.EB == nullptr)
3188 BadUse = true;
3189 }
3190 if (BadUse)
3191 break;
3192 }
3193
3194 if (BadUse)
3195 continue;
3196 ShufIns.push_back(&MI);
3197 }
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208 using InstrGroupList = std::vector;
3209 InstrGroupList Groups;
3210
3211 for (unsigned i = 0, n = ShufIns.size(); i < n; ++i) {
3212 MachineInstr *SI = ShufIns[i];
3213 if (SI == nullptr)
3214 continue;
3215
3216 InstrGroup G;
3217 G.Ins.push_back(SI);
3218 G.Out.Reg = getDefReg(SI);
3220 HBS::getInstrUses(*SI, Inputs);
3221
3222 for (unsigned j = i+1; j < n; ++j) {
3223 MachineInstr *MI = ShufIns[j];
3224 if (MI == nullptr)
3225 continue;
3227 HBS::getInstrDefs(*MI, Defs);
3228
3229 if (!Defs.intersects(Inputs))
3230 continue;
3231
3232
3234 Inputs.remove(Defs);
3235
3236 HBS::getInstrUses(*MI, Inputs);
3237 ShufIns[j] = nullptr;
3238 }
3239
3240
3241 if (Inputs.count() > 1)
3242 continue;
3243 auto LoopInpEq = [G] (const PhiInfo &P) -> bool {
3244 return G.Out.Reg == P.LR.Reg;
3245 };
3247 continue;
3248
3249 G.Inp.Reg = Inputs.find_first();
3251 }
3252
3254 for (unsigned i = 0, n = Groups.size(); i < n; ++i) {
3255 InstrGroup &G = Groups[i];
3256 dbgs() << "Group[" << i << "] inp: "
3257 << printReg(G.Inp.Reg, HRI, G.Inp.Sub)
3258 << " out: " << printReg(G.Out.Reg, HRI, G.Out.Sub) << "\n";
3259 for (const MachineInstr *MI : G.Ins)
3261 }
3262 });
3263
3264 for (InstrGroup &G : Groups) {
3265 if (!isShuffleOf(G.Out.Reg, G.Inp.Reg))
3266 continue;
3267 auto LoopInpEq = [G] (const PhiInfo &P) -> bool {
3268 return G.Out.Reg == P.LR.Reg;
3269 };
3271 if (F == Phis.end())
3272 continue;
3273 unsigned PrehR = 0;
3274 if (!isSameShuffle(G.Out.Reg, G.Inp.Reg, F->PR.Reg, PrehR)) {
3275 const MachineInstr *DefPrehR = MRI->getVRegDef(F->PR.Reg);
3277 if (Opc != Hexagon::A2_tfrsi && Opc != Hexagon::A2_tfrpi)
3278 continue;
3280 continue;
3282 continue;
3283 const TargetRegisterClass *RC = MRI->getRegClass(G.Inp.Reg);
3284 if (RC != MRI->getRegClass(F->PR.Reg)) {
3285 PrehR = MRI->createVirtualRegister(RC);
3286 unsigned TfrI = (RC == &Hexagon::IntRegsRegClass) ? Hexagon::A2_tfrsi
3287 : Hexagon::A2_tfrpi;
3288 auto T = C.PB->getFirstTerminator();
3290 BuildMI(*C.PB, T, DL, HII->get(TfrI), PrehR)
3292 } else {
3293 PrehR = F->PR.Reg;
3294 }
3295 }
3296
3297
3298
3299
3300
3301 if (MRI->getRegClass(PrehR) != MRI->getRegClass(G.Inp.Reg))
3302 continue;
3303 moveGroup(G, *F->LB, *F->PB, F->LB->getFirstNonPHI(), F->DefR, PrehR);
3305 }
3306
3308}
3309
3310bool HexagonLoopRescheduling::runOnMachineFunction(MachineFunction &MF) {
3312 return false;
3313
3314 auto &HST = MF.getSubtarget();
3315 HII = HST.getInstrInfo();
3318 const HexagonEvaluator HE(*HRI, *MRI, *HII, MF);
3319 BitTracker BT(HE, MF);
3322 BTP = &BT;
3323
3324 std::vector Cand;
3325
3326 for (auto &B : MF) {
3327 if (B.pred_size() != 2 || B.succ_size() != 2)
3328 continue;
3329 MachineBasicBlock *PB = nullptr;
3330 bool IsLoop = false;
3331 for (MachineBasicBlock *Pred : B.predecessors()) {
3332 if (Pred != &B)
3333 PB = Pred;
3334 else
3335 IsLoop = true;
3336 }
3337 if (!IsLoop)
3338 continue;
3339
3340 MachineBasicBlock *EB = nullptr;
3341 for (MachineBasicBlock *Succ : B.successors()) {
3342 if (Succ == &B)
3343 continue;
3344
3345
3346 if (Succ->pred_size() == 1)
3347 EB = Succ;
3348 break;
3349 }
3350
3351 Cand.push_back(LoopCand(&B, PB, EB));
3352 }
3353
3355 for (auto &C : Cand)
3357
3359}
3360
3361
3362
3363
3364
3366 return new HexagonLoopRescheduling();
3367}
3368
3370 return new HexagonBitSimplify();
3371}
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file implements the BitVector class.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< ArrayRef< InsnRange >::iterator > intersects(const MachineInstr *StartMI, const MachineInstr *EndMI, ArrayRef< InsnRange > Ranges, const InstructionOrdering &Ordering)
Check if the instruction range [StartMI, EndMI] intersects any instruction range in Ranges.
static unsigned CountBitSplit
Definition HexagonBitSimplify.cpp:49
static cl::opt< bool > PreserveTiedOps("hexbit-keep-tied", cl::Hidden, cl::init(true), cl::desc("Preserve subregisters in tied operands"))
static cl::opt< bool > GenExtract("hexbit-extract", cl::Hidden, cl::init(true), cl::desc("Generate extract instructions"))
static cl::opt< unsigned > MaxBitSplit("hexbit-max-bitsplit", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static cl::opt< bool > GenBitSplit("hexbit-bitsplit", cl::Hidden, cl::init(true), cl::desc("Generate bitsplit instructions"))
static cl::opt< unsigned > MaxExtract("hexbit-max-extract", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static cl::opt< unsigned > RegisterSetLimit("hexbit-registerset-limit", cl::Hidden, cl::init(1000))
static unsigned CountExtract
Definition HexagonBitSimplify.cpp:46
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Promote Memory to Register
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)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Remove Loads Into Fake Uses
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
This file defines the SmallVector class.
SmallSet< unsigned, 4 > RegisterSet
static const X86InstrFMA3Group Groups[]
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
bool subsetOf(const BitVector &RHS) const
subsetOf - Check if This is a subset of RHS.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
unsigned getHexagonSubRegIndex(const TargetRegisterClass &RC, unsigned GenIdx) const
const HexagonRegisterInfo * getRegisterInfo() const override
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & front() const
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
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool isDebugInstr() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
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.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
std::pair< const_iterator, bool > insert(const unsigned &V)
void push_back(const T &Elt)
unsigned getID() const
Return the register class ID number.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char IsConst[]
Key for Kernel::Arg::Metadata::mIsConst.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
SmallVector< const MachineInstr * > InstrList
bool isConst(unsigned Opc)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool includes(R1 &&Range1, R2 &&Range2)
Provide wrappers to std::includes which take ranges instead of having to pass begin/end explicitly.
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionPass * createHexagonBitSimplify()
Definition HexagonBitSimplify.cpp:3369
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
FunctionPass * createHexagonLoopRescheduling()
Definition HexagonBitSimplify.cpp:3365
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Sub
Subtraction of integers.
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
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.
Maximum remaining allocation size observed for a phi node, and how often the allocation size has alre...
bool is(unsigned T) const
static BitValue self(const BitRef &Self=BitRef())
bool has(unsigned Reg) const
const RegisterCell & lookup(unsigned Reg) const
bool reached(const MachineBasicBlock *B) const
void trace(bool On=false)
void put(RegisterRef RR, const RegisterCell &RC)
void visit(const MachineInstr &MI)
RegisterCell get(RegisterRef RR) const