10 #define DEBUG_TYPE "hexbit"
68 unsigned find_first()
const {
75 unsigned find_next(
unsigned Prev)
const {
83 unsigned Idx = v2x(R);
88 unsigned Idx = v2x(R);
101 reference operator[](
unsigned R) {
102 unsigned Idx = v2x(R);
106 bool operator[](
unsigned R)
const {
107 unsigned Idx = v2x(R);
111 bool has(
unsigned R)
const {
112 unsigned Idx = v2x(R);
123 return !Rs.BitVector::test(*
this);
130 void ensure(
unsigned Idx) {
132 resize(std::max(Idx+1, 32U));
135 static inline unsigned v2x(
unsigned v) {
139 static inline unsigned x2v(
unsigned x) {
149 const PrintRegSet &
P);
160 for (
unsigned R = P.RS.find_first(); R; R = P.RS.find_next(R))
166 class Transformation;
177 return "Hexagon bit simplification";
195 uint16_t W, uint64_t &U);
196 static bool replaceReg(
unsigned OldR,
unsigned NewR,
200 static bool replaceRegWithSub(
unsigned OldR,
unsigned NewR,
202 static bool replaceSubWithSub(
unsigned OldR,
unsigned OldSR,
208 static bool getUsedBitsInStore(
unsigned Opc,
BitVector &
Bits,
210 static bool getUsedBits(
unsigned Opc,
unsigned OpN,
BitVector &
Bits,
223 unsigned NewSub = Hexagon::NoSubRegister);
227 typedef HexagonBitSimplify HBS;
232 class Transformation {
236 Transformation(
bool TD) : TopDown(TD) {}
237 virtual ~Transformation() =
default;
245 "Hexagon bit simplification",
false,
false)
254 bool Changed =
false;
257 Changed = T.processBlock(B, AVs);
261 getInstrDefs(
I, Defs);
265 for (
auto I = GTN::child_begin(N),
E = GTN::child_end(N);
I !=
E; ++
I) {
267 Changed |= visitBlock(*SB, T, NewAVs);
270 Changed |= T.processBlock(B, AVs);
281 if (!
Op.isReg() || !
Op.isDef())
283 unsigned R =
Op.getReg();
290 void HexagonBitSimplify::getInstrUses(
const MachineInstr &MI,
293 if (!
Op.isReg() || !
Op.isUse())
295 unsigned R =
Op.getReg();
306 for (uint16_t
i = 0;
i < W; ++
i) {
313 if (RC1[B1+
i] != RC2[B2+
i])
320 uint16_t
B, uint16_t W) {
322 for (uint16_t
i = B;
i < B+W; ++
i)
329 uint16_t B, uint16_t W, uint64_t &U) {
332 for (uint16_t
i = B+W;
i >
B; --
i) {
344 bool HexagonBitSimplify::replaceReg(
unsigned OldR,
unsigned NewR,
351 for (auto
I = Begin;
I !=
End;
I = NextI) {
352 NextI = std::next(
I);
358 bool HexagonBitSimplify::replaceRegWithSub(
unsigned OldR,
unsigned NewR,
363 if (hasTiedUse(OldR, MRI, NewSR))
367 for (auto
I = Begin;
I !=
End;
I = NextI) {
368 NextI = std::next(
I);
375 bool HexagonBitSimplify::replaceSubWithSub(
unsigned OldR,
unsigned OldSR,
380 if (OldSR != NewSR && hasTiedUse(OldR, MRI, NewSR))
384 for (auto
I = Begin;
I != End;
I = NextI) {
385 NextI = std::next(
I);
386 if (
I->getSubReg() != OldSR)
408 switch (RC->
getID()) {
409 case Hexagon::DoubleRegsRegClassID:
410 case Hexagon::VecDblRegsRegClassID:
411 case Hexagon::VecDblRegs128BRegClassID:
413 if (RR.
Sub == Hexagon::isub_hi || RR.
Sub == Hexagon::vsub_hi)
425 bool HexagonBitSimplify::parseRegSequence(
const MachineInstr &
I,
435 assert((Sub1 == SubLo && Sub2 == SubHi) || (Sub1 == SubHi && Sub2 == SubLo));
436 if (Sub1 == SubLo && Sub2 == SubHi) {
441 if (Sub1 == SubHi && Sub2 == SubLo) {
455 bool HexagonBitSimplify::getUsedBitsInStore(
unsigned Opc,
BitVector &
Bits,
457 using namespace Hexagon;
462 case S2_storerbnew_io:
463 case S2_pstorerbt_io:
464 case S2_pstorerbf_io:
465 case S4_pstorerbtnew_io:
466 case S4_pstorerbfnew_io:
467 case S2_pstorerbnewt_io:
468 case S2_pstorerbnewf_io:
469 case S4_pstorerbnewtnew_io:
470 case S4_pstorerbnewfnew_io:
472 case S2_storerbnew_pi:
473 case S2_pstorerbt_pi:
474 case S2_pstorerbf_pi:
475 case S2_pstorerbtnew_pi:
476 case S2_pstorerbfnew_pi:
477 case S2_pstorerbnewt_pi:
478 case S2_pstorerbnewf_pi:
479 case S2_pstorerbnewtnew_pi:
480 case S2_pstorerbnewfnew_pi:
482 case S4_storerbnew_ap:
484 case S2_storerbnew_pr:
486 case S4_storerbnew_ur:
488 case S2_storerbnew_pbr:
490 case S2_storerbnew_pci:
492 case S2_storerbnew_pcr:
494 case S4_storerbnew_rr:
495 case S4_pstorerbt_rr:
496 case S4_pstorerbf_rr:
497 case S4_pstorerbtnew_rr:
498 case S4_pstorerbfnew_rr:
499 case S4_pstorerbnewt_rr:
500 case S4_pstorerbnewf_rr:
501 case S4_pstorerbnewtnew_rr:
502 case S4_pstorerbnewfnew_rr:
504 case S2_storerbnewgp:
505 case S4_pstorerbt_abs:
506 case S4_pstorerbf_abs:
507 case S4_pstorerbtnew_abs:
508 case S4_pstorerbfnew_abs:
509 case S4_pstorerbnewt_abs:
510 case S4_pstorerbnewf_abs:
511 case S4_pstorerbnewtnew_abs:
512 case S4_pstorerbnewfnew_abs:
513 Bits.
set(Begin, Begin+8);
518 case S2_storerhnew_io:
519 case S2_pstorerht_io:
520 case S2_pstorerhf_io:
521 case S4_pstorerhtnew_io:
522 case S4_pstorerhfnew_io:
523 case S2_pstorerhnewt_io:
524 case S2_pstorerhnewf_io:
525 case S4_pstorerhnewtnew_io:
526 case S4_pstorerhnewfnew_io:
528 case S2_storerhnew_pi:
529 case S2_pstorerht_pi:
530 case S2_pstorerhf_pi:
531 case S2_pstorerhtnew_pi:
532 case S2_pstorerhfnew_pi:
533 case S2_pstorerhnewt_pi:
534 case S2_pstorerhnewf_pi:
535 case S2_pstorerhnewtnew_pi:
536 case S2_pstorerhnewfnew_pi:
538 case S4_storerhnew_ap:
540 case S2_storerhnew_pr:
542 case S4_storerhnew_ur:
544 case S2_storerhnew_pbr:
546 case S2_storerhnew_pci:
548 case S2_storerhnew_pcr:
550 case S4_pstorerht_rr:
551 case S4_pstorerhf_rr:
552 case S4_pstorerhtnew_rr:
553 case S4_pstorerhfnew_rr:
554 case S4_storerhnew_rr:
555 case S4_pstorerhnewt_rr:
556 case S4_pstorerhnewf_rr:
557 case S4_pstorerhnewtnew_rr:
558 case S4_pstorerhnewfnew_rr:
560 case S2_storerhnewgp:
561 case S4_pstorerht_abs:
562 case S4_pstorerhf_abs:
563 case S4_pstorerhtnew_abs:
564 case S4_pstorerhfnew_abs:
565 case S4_pstorerhnewt_abs:
566 case S4_pstorerhnewf_abs:
567 case S4_pstorerhnewtnew_abs:
568 case S4_pstorerhnewfnew_abs:
569 Bits.
set(Begin, Begin+16);
574 case S2_pstorerft_io:
575 case S2_pstorerff_io:
576 case S4_pstorerftnew_io:
577 case S4_pstorerffnew_io:
579 case S2_pstorerft_pi:
580 case S2_pstorerff_pi:
581 case S2_pstorerftnew_pi:
582 case S2_pstorerffnew_pi:
590 case S4_pstorerft_rr:
591 case S4_pstorerff_rr:
592 case S4_pstorerftnew_rr:
593 case S4_pstorerffnew_rr:
595 case S4_pstorerft_abs:
596 case S4_pstorerff_abs:
597 case S4_pstorerftnew_abs:
598 case S4_pstorerffnew_abs:
599 Bits.
set(Begin+16, Begin+32);
614 bool HexagonBitSimplify::getUsedBits(
unsigned Opc,
unsigned OpN,
616 using namespace Hexagon;
620 if (OpN ==
D.getNumOperands()-1)
621 return getUsedBitsInStore(Opc, Bits, Begin);
633 Bits.
set(Begin, Begin+8);
646 Bits.
set(Begin, Begin+16);
654 Bits.
set(Begin+16, Begin+32);
664 Bits.
set(Begin, Begin+8);
674 case A2_addh_h16_sat_ll:
676 case A2_addh_l16_sat_ll:
679 case A2_subh_h16_sat_ll:
681 case A2_subh_l16_sat_ll:
682 case M2_mpy_acc_ll_s0:
683 case M2_mpy_acc_ll_s1:
684 case M2_mpy_acc_sat_ll_s0:
685 case M2_mpy_acc_sat_ll_s1:
688 case M2_mpy_nac_ll_s0:
689 case M2_mpy_nac_ll_s1:
690 case M2_mpy_nac_sat_ll_s0:
691 case M2_mpy_nac_sat_ll_s1:
692 case M2_mpy_rnd_ll_s0:
693 case M2_mpy_rnd_ll_s1:
694 case M2_mpy_sat_ll_s0:
695 case M2_mpy_sat_ll_s1:
696 case M2_mpy_sat_rnd_ll_s0:
697 case M2_mpy_sat_rnd_ll_s1:
698 case M2_mpyd_acc_ll_s0:
699 case M2_mpyd_acc_ll_s1:
702 case M2_mpyd_nac_ll_s0:
703 case M2_mpyd_nac_ll_s1:
704 case M2_mpyd_rnd_ll_s0:
705 case M2_mpyd_rnd_ll_s1:
706 case M2_mpyu_acc_ll_s0:
707 case M2_mpyu_acc_ll_s1:
710 case M2_mpyu_nac_ll_s0:
711 case M2_mpyu_nac_ll_s1:
712 case M2_mpyud_acc_ll_s0:
713 case M2_mpyud_acc_ll_s1:
716 case M2_mpyud_nac_ll_s0:
717 case M2_mpyud_nac_ll_s1:
718 if (OpN == 1 || OpN == 2) {
719 Bits.
set(Begin, Begin+16);
726 case A2_addh_h16_sat_lh:
729 case A2_subh_h16_sat_lh:
730 case M2_mpy_acc_lh_s0:
731 case M2_mpy_acc_lh_s1:
732 case M2_mpy_acc_sat_lh_s0:
733 case M2_mpy_acc_sat_lh_s1:
736 case M2_mpy_nac_lh_s0:
737 case M2_mpy_nac_lh_s1:
738 case M2_mpy_nac_sat_lh_s0:
739 case M2_mpy_nac_sat_lh_s1:
740 case M2_mpy_rnd_lh_s0:
741 case M2_mpy_rnd_lh_s1:
742 case M2_mpy_sat_lh_s0:
743 case M2_mpy_sat_lh_s1:
744 case M2_mpy_sat_rnd_lh_s0:
745 case M2_mpy_sat_rnd_lh_s1:
746 case M2_mpyd_acc_lh_s0:
747 case M2_mpyd_acc_lh_s1:
750 case M2_mpyd_nac_lh_s0:
751 case M2_mpyd_nac_lh_s1:
752 case M2_mpyd_rnd_lh_s0:
753 case M2_mpyd_rnd_lh_s1:
754 case M2_mpyu_acc_lh_s0:
755 case M2_mpyu_acc_lh_s1:
758 case M2_mpyu_nac_lh_s0:
759 case M2_mpyu_nac_lh_s1:
760 case M2_mpyud_acc_lh_s0:
761 case M2_mpyud_acc_lh_s1:
764 case M2_mpyud_nac_lh_s0:
765 case M2_mpyud_nac_lh_s1:
768 case A2_addh_l16_sat_hl:
770 case A2_subh_l16_sat_hl:
772 Bits.
set(Begin, Begin+16);
776 Bits.
set(Begin+16, Begin+32);
783 case A2_addh_h16_sat_hl:
786 case A2_subh_h16_sat_hl:
787 case M2_mpy_acc_hl_s0:
788 case M2_mpy_acc_hl_s1:
789 case M2_mpy_acc_sat_hl_s0:
790 case M2_mpy_acc_sat_hl_s1:
793 case M2_mpy_nac_hl_s0:
794 case M2_mpy_nac_hl_s1:
795 case M2_mpy_nac_sat_hl_s0:
796 case M2_mpy_nac_sat_hl_s1:
797 case M2_mpy_rnd_hl_s0:
798 case M2_mpy_rnd_hl_s1:
799 case M2_mpy_sat_hl_s0:
800 case M2_mpy_sat_hl_s1:
801 case M2_mpy_sat_rnd_hl_s0:
802 case M2_mpy_sat_rnd_hl_s1:
803 case M2_mpyd_acc_hl_s0:
804 case M2_mpyd_acc_hl_s1:
807 case M2_mpyd_nac_hl_s0:
808 case M2_mpyd_nac_hl_s1:
809 case M2_mpyd_rnd_hl_s0:
810 case M2_mpyd_rnd_hl_s1:
811 case M2_mpyu_acc_hl_s0:
812 case M2_mpyu_acc_hl_s1:
815 case M2_mpyu_nac_hl_s0:
816 case M2_mpyu_nac_hl_s1:
817 case M2_mpyud_acc_hl_s0:
818 case M2_mpyud_acc_hl_s1:
821 case M2_mpyud_nac_hl_s0:
822 case M2_mpyud_nac_hl_s1:
824 Bits.
set(Begin+16, Begin+32);
828 Bits.
set(Begin, Begin+16);
835 case A2_addh_h16_sat_hh:
838 case A2_subh_h16_sat_hh:
839 case M2_mpy_acc_hh_s0:
840 case M2_mpy_acc_hh_s1:
841 case M2_mpy_acc_sat_hh_s0:
842 case M2_mpy_acc_sat_hh_s1:
845 case M2_mpy_nac_hh_s0:
846 case M2_mpy_nac_hh_s1:
847 case M2_mpy_nac_sat_hh_s0:
848 case M2_mpy_nac_sat_hh_s1:
849 case M2_mpy_rnd_hh_s0:
850 case M2_mpy_rnd_hh_s1:
851 case M2_mpy_sat_hh_s0:
852 case M2_mpy_sat_hh_s1:
853 case M2_mpy_sat_rnd_hh_s0:
854 case M2_mpy_sat_rnd_hh_s1:
855 case M2_mpyd_acc_hh_s0:
856 case M2_mpyd_acc_hh_s1:
859 case M2_mpyd_nac_hh_s0:
860 case M2_mpyd_nac_hh_s1:
861 case M2_mpyd_rnd_hh_s0:
862 case M2_mpyd_rnd_hh_s1:
863 case M2_mpyu_acc_hh_s0:
864 case M2_mpyu_acc_hh_s1:
867 case M2_mpyu_nac_hh_s0:
868 case M2_mpyu_nac_hh_s1:
869 case M2_mpyud_acc_hh_s0:
870 case M2_mpyud_acc_hh_s1:
873 case M2_mpyud_nac_hh_s0:
874 case M2_mpyud_nac_hh_s1:
875 if (OpN == 1 || OpN == 2) {
876 Bits.
set(Begin+16, Begin+32);
903 switch (RC->
getID()) {
904 case Hexagon::DoubleRegsRegClassID:
905 VerifySR(RC, RR.
Sub);
906 return &Hexagon::IntRegsRegClass;
907 case Hexagon::VecDblRegsRegClassID:
908 VerifySR(RC, RR.
Sub);
909 return &Hexagon::VectorRegsRegClass;
910 case Hexagon::VecDblRegs128BRegClassID:
911 VerifySR(RC, RR.
Sub);
912 return &Hexagon::VectorRegs128BRegClass;
927 auto *DRC = getFinalVRegClass(RD, MRI);
931 return DRC == getFinalVRegClass(RS, MRI);
940 return Op.getSubReg() != NewSub &&
Op.isTied();
946 class DeadCodeElimination {
950 MDT(mdt), MRI(mf.getRegInfo()) {}
953 return runOnNode(MDT.getRootNode());
957 bool isDead(
unsigned R)
const;
968 bool DeadCodeElimination::isDead(
unsigned R)
const {
985 bool Changed =
false;
987 for (
auto I = GTN::child_begin(N),
E = GTN::child_end(N); I !=
E; ++
I)
988 Changed |= runOnNode(*I);
991 std::vector<MachineInstr*> Instrs;
993 Instrs.push_back(&*I);
995 for (
auto MI : Instrs) {
1009 bool AllDead =
true;
1012 if (!
Op.isReg() || !
Op.isDef())
1014 unsigned R =
Op.getReg();
1025 for (
unsigned i = 0, n = Regs.
size();
i != n; ++
i)
1045 class RedundantInstrElimination :
public Transformation {
1049 : Transformation(
true), HII(hii), MRI(mri),
BT(bt) {}
1054 bool isLossyShiftLeft(
const MachineInstr &MI,
unsigned OpN,
1055 unsigned &LostB,
unsigned &LostE);
1056 bool isLossyShiftRight(
const MachineInstr &MI,
unsigned OpN,
1057 unsigned &LostB,
unsigned &LostE);
1058 bool computeUsedBits(
unsigned Reg,
BitVector &Bits);
1073 bool RedundantInstrElimination::isLossyShiftLeft(
const MachineInstr &MI,
1074 unsigned OpN,
unsigned &LostB,
unsigned &LostE) {
1075 using namespace Hexagon;
1078 unsigned ImN, RegN, Width;
1085 case S2_asl_i_p_acc:
1086 case S2_asl_i_p_and:
1087 case S2_asl_i_p_nac:
1089 case S2_asl_i_p_xacc:
1099 case S2_addasl_rrri:
1100 case S4_andi_asl_ri:
1102 case S4_addi_asl_ri:
1103 case S4_subi_asl_ri:
1104 case S2_asl_i_r_acc:
1105 case S2_asl_i_r_and:
1106 case S2_asl_i_r_nac:
1108 case S2_asl_i_r_sat:
1109 case S2_asl_i_r_xacc:
1133 bool RedundantInstrElimination::isLossyShiftRight(
const MachineInstr &MI,
1134 unsigned OpN,
unsigned &LostB,
unsigned &LostE) {
1135 using namespace Hexagon;
1145 case S2_asr_i_p_acc:
1146 case S2_asr_i_p_and:
1147 case S2_asr_i_p_nac:
1149 case S2_lsr_i_p_acc:
1150 case S2_lsr_i_p_and:
1151 case S2_lsr_i_p_nac:
1153 case S2_lsr_i_p_xacc:
1162 case S4_andi_lsr_ri:
1164 case S4_addi_lsr_ri:
1165 case S4_subi_lsr_ri:
1166 case S2_asr_i_r_acc:
1167 case S2_asr_i_r_and:
1168 case S2_asr_i_r_nac:
1170 case S2_lsr_i_r_acc:
1171 case S2_lsr_i_r_and:
1172 case S2_lsr_i_r_nac:
1174 case S2_lsr_i_r_xacc:
1197 bool RedundantInstrElimination::computeUsedBits(
unsigned Reg,
BitVector &Bits) {
1200 std::vector<unsigned> Pending;
1201 Pending.push_back(Reg);
1203 for (
unsigned i = 0;
i < Pending.size(); ++
i) {
1204 unsigned R = Pending[
i];
1211 if (!HBS::getSubregMask(UR, B, W, MRI))
1218 Pending.push_back(DefR);
1243 bool RedundantInstrElimination::computeUsedBits(
const MachineInstr &MI,
1244 unsigned OpN,
BitVector &Bits, uint16_t Begin) {
1247 bool GotBits = HBS::getUsedBits(Opc, OpN, T, Begin, HII);
1252 if (isLossyShiftLeft(MI, OpN, LB, LE) || isLossyShiftRight(MI, OpN, LB, LE)) {
1256 uint16_t Width = RC->
getSize()*8;
1259 T.set(Begin, Begin+Width);
1260 assert(LB <= LE && LB < Width && LE <= Width);
1261 T.reset(Begin+LB, Begin+LE);
1277 if (!HBS::getSubregMask(RD, DB, DW, MRI))
1280 if (!HBS::getSubregMask(RS, SB, SW, MRI))
1286 if (!computeUsedBits(RD.
Reg, Used))
1289 for (
unsigned i = 0;
i != DW; ++
i)
1290 if (Used[
i+DB] && DC[DB+
i] != SC[SB+
i])
1299 bool Changed =
false;
1301 for (
auto I = B.
begin(),
E = B.
end(), NextI =
I; I !=
E; ++
I) {
1302 NextI = std::next(I);
1305 if (MI->
getOpcode() == TargetOpcode::COPY)
1321 for (
auto &
Op : MI->
uses()) {
1327 if (!HBS::isTransparentCopy(RD, RS, MRI))
1331 if (!HBS::getSubregMask(RS, BN, BW, MRI))
1335 if (!usedBitsEqual(RD, RS) && !
HBS::isEqual(DC, 0, SC, BN, BW))
1343 BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
1344 .addReg(RS.
Reg, 0, RS.
Sub);
1345 HBS::replaceSubWithSub(RD.
Reg, RD.
Sub, NewR, 0, MRI);
1368 class ConstGeneration :
public Transformation {
1372 : Transformation(
true), HII(hii), MRI(mri),
BT(bt) {}
1388 bool ConstGeneration::isTfrConst(
const MachineInstr &MI) {
1391 case Hexagon::A2_combineii:
1392 case Hexagon::A4_combineii:
1393 case Hexagon::A2_tfrsi:
1394 case Hexagon::A2_tfrpi:
1395 case Hexagon::PS_true:
1396 case Hexagon::PS_false:
1398 case Hexagon::CONST64:
1409 if (RC == &Hexagon::IntRegsRegClass) {
1410 BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrsi),
Reg)
1411 .addImm(int32_t(C));
1415 if (RC == &Hexagon::DoubleRegsRegClass) {
1417 BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrpi),
Reg)
1424 unsigned Opc =
isInt<8>(
Lo) ? Hexagon::A2_combineii
1425 : Hexagon::A4_combineii;
1427 .addImm(int32_t(
Hi))
1428 .addImm(int32_t(Lo));
1432 BuildMI(B, At, DL, HII.get(Hexagon::CONST64),
Reg)
1437 if (RC == &Hexagon::PredRegsRegClass) {
1440 Opc = Hexagon::PS_false;
1441 else if ((C & 0xFF) == 0xFF)
1442 Opc = Hexagon::PS_true;
1455 bool Changed =
false;
1458 for (
auto I = B.
begin(),
E = B.
end(); I !=
E; ++
I) {
1462 HBS::getInstrDefs(*I, Defs);
1463 if (Defs.count() != 1)
1465 unsigned DR = Defs.find_first();
1470 if (HBS::getConst(DRC, 0, DRC.
width(), U)) {
1474 unsigned ImmReg = genTfrConst(MRI.
getRegClass(DR),
C,
B, At, DL);
1476 HBS::replaceReg(DR, ImmReg, MRI);
1477 BT.
put(ImmReg, DRC);
1490 class CopyGeneration :
public Transformation {
1494 : Transformation(
true), HII(hii), HRI(hri), MRI(mri),
BT(bt) {}
1511 class CopyPropagation :
public Transformation {
1514 : Transformation(
false), HRI(hri), MRI(mri) {}
1518 static bool isCopyReg(
unsigned Opc,
bool NoConv);
1536 auto *FRC = HBS::getFinalVRegClass(Inp, MRI);
1538 if (!HBS::getSubregMask(Inp, B, W, MRI))
1541 for (
unsigned R = AVs.find_first(); R; R = AVs.find_next(R)) {
1542 if (!
BT.
has(R) || Forbidden[R])
1545 unsigned RW = RC.
width();
1549 if (!HBS::isTransparentCopy(R, Inp, MRI))
1562 if (MRI.
getRegClass(R) != &Hexagon::DoubleRegsRegClass)
1566 Out.
Sub = Hexagon::isub_lo;
1568 Out.
Sub = Hexagon::isub_hi;
1572 if (HBS::isTransparentCopy(Out, Inp, MRI))
1583 bool Changed =
false;
1586 for (
auto I = B.
begin(),
E = B.
end(), NextI =
I; I !=
E;
1587 ++
I, AVB.insert(Defs)) {
1588 NextI = std::next(I);
1590 HBS::getInstrDefs(*I, Defs);
1593 if (CopyPropagation::isCopyReg(Opc,
false) ||
1594 ConstGeneration::isTfrConst(*I))
1600 for (
unsigned R = Defs.find_first(); R; R = Defs.find_next(R)) {
1602 auto *FRC = HBS::getFinalVRegClass(R, MRI);
1604 if (findMatch(R, MR, AVB)) {
1606 BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
1607 .addReg(MR.
Reg, 0, MR.
Sub);
1609 HBS::replaceReg(R, NewR, MRI);
1610 Forbidden.insert(R);
1614 if (FRC == &Hexagon::DoubleRegsRegClass ||
1615 FRC == &Hexagon::VecDblRegsRegClass ||
1616 FRC == &Hexagon::VecDblRegs128BRegClass) {
1623 if (findMatch(TL, ML, AVB) && findMatch(TH, MH, AVB)) {
1624 auto *FRC = HBS::getFinalVRegClass(R, MRI);
1626 BuildMI(B, At, DL, HII.get(TargetOpcode::REG_SEQUENCE), NewR)
1627 .addReg(ML.
Reg, 0, ML.
Sub)
1632 HBS::replaceReg(R, NewR, MRI);
1633 Forbidden.insert(R);
1642 bool CopyPropagation::isCopyReg(
unsigned Opc,
bool NoConv) {
1644 case TargetOpcode::COPY:
1645 case TargetOpcode::REG_SEQUENCE:
1646 case Hexagon::A4_combineir:
1647 case Hexagon::A4_combineri:
1649 case Hexagon::A2_tfr:
1650 case Hexagon::A2_tfrp:
1651 case Hexagon::A2_combinew:
1652 case Hexagon::V6_vcombine:
1653 case Hexagon::V6_vcombine_128B:
1661 bool CopyPropagation::propagateRegCopy(
MachineInstr &MI) {
1662 bool Changed =
false;
1668 case TargetOpcode::COPY:
1669 case Hexagon::A2_tfr:
1670 case Hexagon::A2_tfrp: {
1672 if (!HBS::isTransparentCopy(RD, RS, MRI))
1675 Changed = HBS::replaceRegWithSub(RD.
Reg, RS.
Reg, RS.
Sub, MRI);
1677 Changed = HBS::replaceReg(RD.
Reg, RS.
Reg, MRI);
1680 case TargetOpcode::REG_SEQUENCE: {
1682 if (HBS::parseRegSequence(MI, SL, SH, MRI)) {
1686 Changed = HBS::replaceSubWithSub(RD.
Reg, SubLo, SL.
Reg, SL.
Sub, MRI);
1687 Changed |= HBS::replaceSubWithSub(RD.
Reg, SubHi, SH.
Reg, SH.
Sub, MRI);
1691 case Hexagon::A2_combinew:
1692 case Hexagon::V6_vcombine:
1693 case Hexagon::V6_vcombine_128B: {
1698 Changed = HBS::replaceSubWithSub(RD.
Reg, SubLo, RL.Reg, RL.Sub, MRI);
1699 Changed |= HBS::replaceSubWithSub(RD.
Reg, SubHi, RH.
Reg, RH.
Sub, MRI);
1702 case Hexagon::A4_combineir:
1703 case Hexagon::A4_combineri: {
1704 unsigned SrcX = (Opc == Hexagon::A4_combineir) ? 2 : 1;
1705 unsigned Sub = (Opc == Hexagon::A4_combineir) ? Hexagon::isub_lo
1708 Changed = HBS::replaceSubWithSub(RD.
Reg, Sub, RS.
Reg, RS.
Sub, MRI);
1716 std::vector<MachineInstr*> Instrs;
1718 Instrs.push_back(&*I);
1720 bool Changed =
false;
1721 for (
auto I : Instrs) {
1723 if (!CopyPropagation::isCopyReg(Opc,
true))
1725 Changed |= propagateRegCopy(*I);
1736 class BitSimplification :
public Transformation {
1741 : Transformation(
true), HII(hii), HRI(hri), MRI(mri), MF(mf),
BT(bt) {}
1751 unsigned B, RegHalf &RH);
1756 unsigned getCombineOpcode(
bool HLow,
bool LLow);
1783 bool BitSimplification::matchHalf(
unsigned SelfR,
1794 while (I < B+16 && RC[I].num())
1799 unsigned Reg = RC[
I].RefI.Reg;
1800 unsigned P = RC[
I].RefI.Pos;
1803 unsigned Pos = P - (I-
B);
1805 if (Reg == 0 || Reg == SelfR)
1813 if (Pos+16 > SC.
width())
1816 for (
unsigned i = 0;
i < 16; ++
i) {
1825 if (RC[
i+B] != SC[
i+Pos])
1832 Sub = Hexagon::isub_lo;
1836 Sub = Hexagon::isub_lo;
1840 Sub = Hexagon::isub_hi;
1844 Sub = Hexagon::isub_hi;
1855 if (!HBS::getFinalVRegClass(RH, MRI))
1863 auto *OpRC = HII.getRegClass(HII.get(Opc), OpNum, &HRI, MF);
1864 auto *
RRC = HBS::getFinalVRegClass(R, MRI);
1865 return OpRC->hasSubClassEq(
RRC);
1870 bool BitSimplification::matchPackhl(
unsigned SelfR,
1873 RegHalf L1, H1, L2, H2;
1875 if (!matchHalf(SelfR, RC, 0, L2) || !matchHalf(SelfR, RC, 16, L1))
1877 if (!matchHalf(SelfR, RC, 32, H2) || !matchHalf(SelfR, RC, 48, H1))
1881 if (H1.Reg != L1.Reg || H1.Sub != L1.Sub || H1.Low || !L1.Low)
1883 if (H2.Reg != L2.Reg || H2.Sub != L2.Sub || H2.Low || !L2.Low)
1891 unsigned BitSimplification::getCombineOpcode(
bool HLow,
bool LLow) {
1892 return HLow ? LLow ? Hexagon::A2_combine_ll
1893 : Hexagon::A2_combine_lh
1894 : LLow ? Hexagon::A2_combine_hl
1895 : Hexagon::A2_combine_hh;
1901 bool BitSimplification::genStoreUpperHalf(
MachineInstr *MI) {
1903 if (Opc != Hexagon::S2_storerh_io)
1912 if (!matchHalf(0, RC, 0, H))
1916 MI->
setDesc(HII.get(Hexagon::S2_storerf_io));
1924 bool BitSimplification::genStoreImmediate(
MachineInstr *MI) {
1928 case Hexagon::S2_storeri_io:
1930 case Hexagon::S2_storerh_io:
1932 case Hexagon::S2_storerb_io:
1945 int64_t Off = OffOp.
getImm();
1947 if (!
isUIntN(6+Align, Off) || (Off & ((1<<Align)-1)))
1955 if (!HBS::getConst(RC, 0, RC.
width(), U))
1961 case Hexagon::S2_storerb_io:
1964 case Hexagon::S2_storerh_io:
1967 case Hexagon::S2_storeri_io:
1976 case Hexagon::S2_storerb_io:
1977 MI->
setDesc(HII.get(Hexagon::S4_storeirb_io));
1979 case Hexagon::S2_storerh_io:
1980 MI->
setDesc(HII.get(Hexagon::S4_storeirh_io));
1982 case Hexagon::S2_storeri_io:
1983 MI->
setDesc(HII.get(Hexagon::S4_storeiri_io));
1997 if (Opc == Hexagon::S2_packhl)
2000 if (!matchPackhl(RD.
Reg, RC, Rs, Rt))
2002 if (!validateReg(Rs, Hexagon::S2_packhl, 1) ||
2003 !validateReg(Rt, Hexagon::S2_packhl, 2))
2011 BuildMI(B, At, DL, HII.get(Hexagon::S2_packhl), NewR)
2012 .addReg(Rs.
Reg, 0, Rs.
Sub)
2014 HBS::replaceSubWithSub(RD.
Reg, RD.
Sub, NewR, 0, MRI);
2021 bool BitSimplification::genExtractHalf(
MachineInstr *MI,
2037 if (L.Low && Opc != Hexagon::A2_zxth) {
2038 if (validateReg(L, Hexagon::A2_zxth, 1)) {
2040 BuildMI(B, At, DL, HII.get(Hexagon::A2_zxth), NewR)
2041 .addReg(L.Reg, 0, L.Sub);
2043 }
else if (!L.Low && Opc != Hexagon::S2_lsr_i_r) {
2044 if (validateReg(L, Hexagon::S2_lsr_i_r, 1)) {
2046 BuildMI(B, MI, DL, HII.get(Hexagon::S2_lsr_i_r), NewR)
2047 .addReg(L.Reg, 0, L.Sub)
2053 HBS::replaceSubWithSub(RD.
Reg, RD.
Sub, NewR, 0, MRI);
2060 bool BitSimplification::genCombineHalf(
MachineInstr *MI,
2064 if (!matchHalf(RD.
Reg, RC, 0, L) || !matchHalf(RD.
Reg, RC, 16, H))
2067 if (L.Reg == H.Reg && L.Sub == H.Sub && !H.Low && L.Low)
2071 unsigned COpc = getCombineOpcode(H.Low, L.Low);
2074 if (!validateReg(H, COpc, 1) || !validateReg(L, COpc, 2))
2082 BuildMI(B, At, DL, HII.get(COpc), NewR)
2083 .addReg(H.Reg, 0, H.Sub)
2084 .
addReg(L.Reg, 0, L.Sub);
2085 HBS::replaceSubWithSub(RD.
Reg, RD.
Sub, NewR, 0, MRI);
2092 bool BitSimplification::genExtractLow(
MachineInstr *MI,
2096 case Hexagon::A2_zxtb:
2097 case Hexagon::A2_zxth:
2098 case Hexagon::S2_extractu:
2109 unsigned W = RC.
width();
2110 while (W > 0 && RC[W-1].is(0))
2112 if (W == 0 || W == RC.
width())
2114 unsigned NewOpc = (W == 8) ? Hexagon::A2_zxtb
2115 : (W == 16) ? Hexagon::A2_zxth
2116 : (W < 10) ? Hexagon::A2_andir
2117 : Hexagon::S2_extractu;
2121 for (
auto &
Op : MI->
uses()) {
2129 if (!HBS::getSubregMask(RS, BN, BW, MRI))
2133 if (!validateReg(RS, NewOpc, 1))
2139 auto MIB =
BuildMI(B, At, DL, HII.get(NewOpc), NewR)
2140 .addReg(RS.
Reg, 0, RS.
Sub);
2141 if (NewOpc == Hexagon::A2_andir)
2142 MIB.addImm((1 << W) - 1);
2143 else if (NewOpc == Hexagon::S2_extractu)
2144 MIB.addImm(W).addImm(0);
2145 HBS::replaceSubWithSub(RD.
Reg, RD.
Sub, NewR, 0, MRI);
2158 bool BitSimplification::simplifyTstbit(
MachineInstr *MI,
2161 if (Opc != Hexagon::S2_tstbit_i)
2168 if (!
BT.
has(RS.
Reg) || !HBS::getSubregMask(RS, F, W, MRI))
2181 unsigned P = std::numeric_limits<unsigned>::max();
2183 if (TC == &Hexagon::DoubleRegsRegClass) {
2185 RR.Sub = Hexagon::isub_lo;
2188 RR.Sub = Hexagon::isub_hi;
2190 }
else if (TC == &Hexagon::IntRegsRegClass) {
2193 if (P != std::numeric_limits<unsigned>::max()) {
2195 BuildMI(B, At, DL, HII.get(Hexagon::S2_tstbit_i), NewR)
2196 .addReg(RR.Reg, 0, RR.Sub)
2198 HBS::replaceReg(RD.
Reg, NewR, MRI);
2202 }
else if (V.
is(0) || V.
is(1)) {
2204 unsigned NewOpc = V.
is(0) ? Hexagon::PS_false : Hexagon::PS_true;
2205 BuildMI(B, At, DL, HII.get(NewOpc), NewR);
2206 HBS::replaceReg(RD.
Reg, NewR, MRI);
2217 bool Changed =
false;
2221 for (
auto I = B.
begin(),
E = B.
end(); I !=
E; ++
I, AVB.insert(Defs)) {
2224 HBS::getInstrDefs(*MI, Defs);
2227 if (Opc == TargetOpcode::COPY || Opc == TargetOpcode::REG_SEQUENCE)
2231 bool T = genStoreUpperHalf(MI);
2232 T = T || genStoreImmediate(MI);
2237 if (Defs.count() != 1)
2248 if (FRC->
getID() == Hexagon::DoubleRegsRegClassID) {
2249 bool T = genPackhl(MI, RD, RC);
2254 if (FRC->
getID() == Hexagon::IntRegsRegClassID) {
2255 bool T = genExtractHalf(MI, RD, RC);
2256 T = T || genCombineHalf(MI, RD, RC);
2257 T = T || genExtractLow(MI, RD, RC);
2262 if (FRC->
getID() == Hexagon::PredRegsRegClassID) {
2263 bool T = simplifyTstbit(MI, RD, RC);
2277 auto &HII = *HST.getInstrInfo();
2279 MDT = &getAnalysis<MachineDominatorTree>();
2283 Changed = DeadCodeElimination(MF, *MDT).run();
2293 ConstGeneration ImmG(
BT, HII, MRI);
2294 Changed |= visitBlock(Entry, ImmG, AIG);
2297 RedundantInstrElimination RIE(
BT, HII, MRI);
2298 bool Ried = visitBlock(Entry, RIE, ARE);
2305 CopyGeneration CopyG(
BT, HII, HRI, MRI);
2306 Changed |= visitBlock(Entry, CopyG, ACG);
2309 CopyPropagation CopyP(HRI, MRI);
2310 Changed |= visitBlock(Entry, CopyP, ACP);
2312 Changed = DeadCodeElimination(MF, *MDT).run() || Changed;
2316 BitSimplification BitS(
BT, HII, HRI, MRI, MF);
2317 Changed |= visitBlock(Entry, BitS, ABS);
2319 Changed = DeadCodeElimination(MF, *MDT).run() || Changed;
2325 DeadCodeElimination(MF, *MDT).run();
2406 HII(nullptr), HRI(nullptr), MRI(nullptr), BTP(nullptr) {
2423 typedef std::vector<MachineInstr*> InstrList;
2436 bool isConst(
unsigned Reg)
const;
2437 bool isBitShuffle(
const MachineInstr *MI,
unsigned DefR)
const;
2438 bool isStoreInput(
const MachineInstr *MI,
unsigned DefR)
const;
2439 bool isShuffleOf(
unsigned OutR,
unsigned InpR)
const;
2440 bool isSameShuffle(
unsigned OutR1,
unsigned InpR1,
unsigned OutR2,
2441 unsigned &InpR2)
const;
2444 bool processLoop(LoopCand &C);
2452 "Hexagon Loop Rescheduling",
false,
false)
2454 HexagonLoopRescheduling::PhiInfo::PhiInfo(
MachineInstr &P,
2456 DefR = HexagonLoopRescheduling::getDefReg(&P);
2459 for (
unsigned i = 1, n = P.getNumOperands();
i < n;
i += 2) {
2462 LR = P.getOperand(
i);
2466 PR = P.getOperand(
i);
2470 unsigned HexagonLoopRescheduling::getDefReg(
const MachineInstr *MI) {
2472 HBS::getInstrDefs(*MI, Defs);
2473 if (Defs.count() != 1)
2475 return Defs.find_first();
2478 bool HexagonLoopRescheduling::isConst(
unsigned Reg)
const {
2482 for (
unsigned i = 0, w = RC.
width();
i < w; ++
i) {
2484 if (!V.
is(0) && !V.
is(1))
2490 bool HexagonLoopRescheduling::isBitShuffle(
const MachineInstr *MI,
2491 unsigned DefR)
const {
2494 case TargetOpcode::COPY:
2495 case Hexagon::S2_lsr_i_r:
2496 case Hexagon::S2_asr_i_r:
2497 case Hexagon::S2_asl_i_r:
2498 case Hexagon::S2_lsr_i_p:
2499 case Hexagon::S2_asr_i_p:
2500 case Hexagon::S2_asl_i_p:
2501 case Hexagon::S2_insert:
2502 case Hexagon::A2_or:
2503 case Hexagon::A2_orp:
2504 case Hexagon::A2_and:
2505 case Hexagon::A2_andp:
2506 case Hexagon::A2_combinew:
2507 case Hexagon::A4_combineri:
2508 case Hexagon::A4_combineir:
2509 case Hexagon::A2_combineii:
2510 case Hexagon::A4_combineii:
2511 case Hexagon::A2_combine_ll:
2512 case Hexagon::A2_combine_lh:
2513 case Hexagon::A2_combine_hl:
2514 case Hexagon::A2_combine_hh:
2520 bool HexagonLoopRescheduling::isStoreInput(
const MachineInstr *MI,
2521 unsigned InpR)
const {
2532 bool HexagonLoopRescheduling::isShuffleOf(
unsigned OutR,
unsigned InpR)
const {
2533 if (!BTP->has(OutR) || !BTP->has(InpR))
2536 for (
unsigned i = 0, w = OutC.
width();
i < w; ++
i) {
2546 bool HexagonLoopRescheduling::isSameShuffle(
unsigned OutR1,
unsigned InpR1,
2547 unsigned OutR2,
unsigned &InpR2)
const {
2548 if (!BTP->has(OutR1) || !BTP->has(InpR1) || !BTP->has(OutR2))
2552 unsigned W = OutC1.
width();
2553 unsigned MatchR = 0;
2554 if (W != OutC2.
width())
2556 for (
unsigned i = 0;
i < W; ++
i) {
2562 if (V1.
RefI.
Pos != V2.RefI.Pos)
2566 if (V2.RefI.Reg == 0 || V2.RefI.Reg == OutR2)
2569 MatchR = V2.RefI.Reg;
2570 else if (V2.RefI.Reg != MatchR)
2579 unsigned NewPredR) {
2583 unsigned PhiR = MRI->createVirtualRegister(PhiRC);
2584 BuildMI(LB, At, At->getDebugLoc(), HII->get(TargetOpcode::PHI), PhiR)
2589 RegMap.
insert(std::make_pair(G.Inp.Reg, PhiR));
2591 for (
unsigned i = G.Ins.size();
i > 0; --
i) {
2593 unsigned DR = getDefReg(SI);
2595 unsigned NewDR = MRI->createVirtualRegister(RC);
2607 unsigned UseR = RegMap[Op.
getReg()];
2610 RegMap.
insert(std::make_pair(DR, NewDR));
2613 HBS::replaceReg(OldPhiR, RegMap[G.Out.Reg], *MRI);
2616 bool HexagonLoopRescheduling::processLoop(LoopCand &C) {
2617 DEBUG(
dbgs() <<
"Processing loop in BB#" << C.LB->getNumber() <<
"\n");
2618 std::vector<PhiInfo> Phis;
2619 for (
auto &I : *C.LB) {
2622 unsigned PR = getDefReg(&I);
2625 bool BadUse =
false, GoodUse =
false;
2626 for (
auto UI = MRI->use_begin(PR), UE = MRI->use_end(); UI != UE; ++UI) {
2632 if (isBitShuffle(UseI, PR) || isStoreInput(UseI, PR))
2635 if (BadUse || !GoodUse)
2638 Phis.push_back(PhiInfo(I, *C.LB));
2642 dbgs() <<
"Phis: {";
2643 for (
auto &I : Phis) {
2645 <<
PrintReg(I.PR.Reg, HRI, I.PR.Sub) <<
":b" << I.PB->getNumber()
2646 <<
',' <<
PrintReg(I.LR.Reg, HRI, I.LR.Sub) <<
":b"
2647 << I.LB->getNumber() <<
')';
2655 bool Changed =
false;
2662 for (
auto I = C.LB->rbegin(),
E = C.LB->rend(); I !=
E; ++
I) {
2663 if (I->isTerminator())
2669 HBS::getInstrDefs(*I, Defs);
2670 if (Defs.count() != 1)
2672 unsigned DefR = Defs.find_first();
2675 if (!isBitShuffle(&*I, DefR))
2678 bool BadUse =
false;
2679 for (
auto UI = MRI->use_begin(DefR), UE = MRI->use_end(); UI != UE; ++UI) {
2682 if (UseI->
isPHI()) {
2685 unsigned Idx = UI.getOperandNo();
2689 auto F =
find(ShufIns, UseI);
2690 if (F == ShufIns.end())
2696 if (C.EB ==
nullptr)
2705 ShufIns.push_back(&*I);
2717 typedef std::vector<InstrGroup> InstrGroupList;
2718 InstrGroupList Groups;
2720 for (
unsigned i = 0, n = ShufIns.size();
i < n; ++
i) {
2726 G.Ins.push_back(SI);
2727 G.Out.Reg = getDefReg(SI);
2729 HBS::getInstrUses(*SI, Inputs);
2731 for (
unsigned j =
i+1; j < n; ++j) {
2736 HBS::getInstrDefs(*MI, Defs);
2738 if (!Defs.intersects(Inputs))
2742 G.Ins.push_back(MI);
2743 Inputs.remove(Defs);
2745 HBS::getInstrUses(*MI, Inputs);
2746 ShufIns[j] =
nullptr;
2750 if (Inputs.count() > 1)
2752 auto LoopInpEq = [
G] (
const PhiInfo &
P) ->
bool {
2753 return G.Out.Reg == P.LR.Reg;
2758 G.Inp.Reg = Inputs.find_first();
2759 Groups.push_back(G);
2763 for (
unsigned i = 0, n = Groups.size();
i < n; ++
i) {
2764 InstrGroup &G = Groups[
i];
2765 dbgs() <<
"Group[" <<
i <<
"] inp: "
2766 <<
PrintReg(G.Inp.Reg, HRI, G.Inp.Sub)
2767 <<
" out: " <<
PrintReg(G.Out.Reg, HRI, G.Out.Sub) <<
"\n";
2768 for (
unsigned j = 0, m = G.Ins.size(); j < m; ++j)
2769 dbgs() <<
" " << *G.Ins[j];
2773 for (
unsigned i = 0, n = Groups.size();
i < n; ++
i) {
2774 InstrGroup &G = Groups[
i];
2775 if (!isShuffleOf(G.Out.Reg, G.Inp.Reg))
2777 auto LoopInpEq = [
G] (
const PhiInfo &
P) ->
bool {
2778 return G.Out.Reg == P.LR.Reg;
2781 if (F == Phis.end())
2784 if (!isSameShuffle(G.Out.Reg, G.Inp.Reg, F->PR.Reg, PrehR)) {
2785 const MachineInstr *DefPrehR = MRI->getVRegDef(F->PR.Reg);
2787 if (Opc != Hexagon::A2_tfrsi && Opc != Hexagon::A2_tfrpi)
2794 if (RC != MRI->getRegClass(F->PR.Reg)) {
2795 PrehR = MRI->createVirtualRegister(RC);
2796 unsigned TfrI = (RC == &Hexagon::IntRegsRegClass) ? Hexagon::A2_tfrsi
2797 : Hexagon::A2_tfrpi;
2798 auto T = C.PB->getFirstTerminator();
2800 BuildMI(*C.PB, T, DL, HII->get(TfrI), PrehR)
2811 if (MRI->getRegClass(PrehR) != MRI->getRegClass(G.Inp.Reg))
2813 moveGroup(G, *F->LB, *F->PB, F->LB->getFirstNonPHI(), F->DefR, PrehR);
2820 bool HexagonLoopRescheduling::runOnMachineFunction(
MachineFunction &MF) {
2825 HII = HST.getInstrInfo();
2834 std::vector<LoopCand> Cand;
2836 for (
auto &B : MF) {
2837 if (B.pred_size() != 2 || B.succ_size() != 2)
2840 bool IsLoop =
false;
2841 for (
auto PI = B.pred_begin(), PE = B.pred_end(); PI != PE; ++PI) {
2851 for (
auto SI = B.succ_begin(), SE = B.succ_end(); SI != SE; ++SI) {
2856 if ((*SI)->pred_size() == 1)
2861 Cand.push_back(LoopCand(&B, PB, EB));
2864 bool Changed =
false;
2865 for (
auto &C : Cand)
2866 Changed |= processLoop(C);
2876 return new HexagonLoopRescheduling();
2880 return new HexagonBitSimplify();
void push_back(const T &Elt)
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
size_type size() const
size - Returns the number of bits in this bitvector.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void trace(bool On=false)
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
MachineBasicBlock * getMBB() const
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool anyCommon(const BitVector &RHS) const
Test if any common bits are set.
constexpr uint32_t Lo_32(uint64_t Value)
Lo_32 - This function returns the low 32 bits of a 64 bit value.
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
iterator_range< use_iterator > use_operands(unsigned Reg) const
Describe properties that are true of each instruction in the target description file.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Y = RRC X, rotate right via carry.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
void visit(const MachineInstr &MI)
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
unsigned getID() const
Return the register class ID number.
constexpr bool isInt< 8 >(int64_t x)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
MachineInstrBundleIterator< MachineInstr > iterator
bool any() const
any - Returns true if any bit is set.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
void markUsesInDebugValueAsUndef(unsigned Reg) const
markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the specified register as undefined wh...
unsigned getHexagonSubRegIndex(const TargetRegisterClass *RC, unsigned GenIdx) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned getSize() const
Return the size of the register in bytes, which is also the size of a stack slot allocated to hold a ...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
void clear()
clear - Clear all bits.
static use_iterator use_end()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetRegisterInfo * getTargetRegisterInfo() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const HexagonRegisterInfo * getRegisterInfo() const override
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
RegisterCell get(RegisterRef RR) const
Reg
All possible values of the reg field in the ModR/M byte.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineBasicBlock & front() const
bool is(unsigned T) const
static bool isEqual(const Function &Caller, const Function &Callee)
BitVector & operator|=(const BitVector &RHS)
FunctionPass * createHexagonBitSimplify()
Base class for the actual dominator tree node.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
This corresponds to the llvm.lifetime.
bool isDebugValue() const
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
size_type count() const
count - Returns the number of bits which are set.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
#define LLVM_ATTRIBUTE_UNUSED
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
FunctionPass class - This class is used to implement most global optimizations.
FunctionPass * createHexagonLoopRescheduling()
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
const RegisterCell & lookup(unsigned Reg) const
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
void initializeHexagonBitSimplifyPass(PassRegistry &Registry)
MachineOperand class - Representation of each machine instruction operand.
reference operator[](unsigned Idx)
bool test(unsigned Idx) const
Hexagon bit simplification
CHAIN = SC CHAIN, Imm128 - System call.
static cl::opt< bool > PreserveTiedOps("hexbit-keep-tied", cl::Hidden, cl::init(true), cl::desc("Preserve subregisters in tied operands"))
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
bool has(unsigned Reg) const
INITIALIZE_PASS_BEGIN(HexagonBitSimplify,"hexbit","Hexagon bit simplification", false, false) INITIALIZE_PASS_END(HexagonBitSimplify
Representation of each machine instruction.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
use_iterator use_begin(unsigned RegNo) const
void setReg(unsigned Reg)
Change the register this operand corresponds to.
static MachineOperand CreateImm(int64_t Val)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
void setSubReg(unsigned subReg)
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void initializeHexagonLoopReschedulingPass(PassRegistry &)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
bool reached(const MachineBasicBlock *B) const
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
constexpr uint32_t Hi_32(uint64_t Value)
Hi_32 - This function returns the high 32 bits of a 64 bit value.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
void put(RegisterRef RR, const RegisterCell &RC)
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
std::set< RegisterRef > RegisterSet
INITIALIZE_PASS(HexagonLoopRescheduling,"hexagon-loop-resched","Hexagon Loop Rescheduling", false, false) HexagonLoopRescheduling
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
bool isUIntN(unsigned N, uint64_t x)
isUIntN - Checks if an unsigned integer fits into the given (dynamic) bit width.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...