34 #define DEBUG_TYPE "hexagon-copy-combine"
39 cl::desc(
"Disable merging into combines"));
43 cl::desc(
"Disable generation of const64"));
48 cl::desc(
"Maximum distance between a tfr feeding a store we "
49 "consider the store still to be newifiable"));
78 return "Hexagon Copy-To-Combine Pass";
99 unsigned I1DestReg,
unsigned I2DestReg,
123 "Hexagon Copy-To-Combine Pass",
false,
false)
127 switch (
MI.getOpcode()) {
128 case Hexagon::A2_tfr: {
136 return Hexagon::IntRegsRegClass.contains(DestReg) &&
137 Hexagon::IntRegsRegClass.contains(SrcReg);
140 case Hexagon::A2_tfrsi: {
156 return Hexagon::IntRegsRegClass.contains(DestReg) &&
160 case Hexagon::V6_vassign:
171 if (
I.getOpcode() == Hexagon::TFRI64_V4 ||
172 I.getOpcode() == Hexagon::A2_tfrsi) {
174 return !
Op.isImm() || !isInt<N>(
Op.getImm());
184 unsigned HiOpc = HighRegInst.
getOpcode();
187 auto verifyOpc = [](
unsigned Opc) ->
void {
189 case Hexagon::A2_tfr:
190 case Hexagon::A2_tfrsi:
191 case Hexagon::V6_vassign:
200 if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign)
201 return HiOpc == LoOpc;
205 if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
206 isGreaterThanNBitTFRI<6>(LowRegInst))
212 if (isGreaterThanNBitTFRI<16>(HighRegInst) &&
219 if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
220 isGreaterThanNBitTFRI<8>(LowRegInst))
229 return (
Reg - Hexagon::R0) % 2 == 0;
231 return (
Reg - Hexagon::V0) % 2 == 0;
237 if (
Op.isReg() &&
Op.getReg() == RegNotKilled &&
Op.isKill())
247 MI.modifiesRegister(DestReg,
TRI) ||
MI.readsRegister(DestReg,
TRI) ||
248 MI.hasUnmodeledSideEffects() ||
MI.isInlineAsm() ||
249 MI.isMetaInstruction();
262 bool &DoInsertAtI1) {
267 if (I2UseReg &&
I1.modifiesRegister(I2UseReg,
TRI))
281 End = ++
I1.getIterator().getReverse();
285 unsigned KilledOperand = 0;
287 KilledOperand = I2UseReg;
290 for (;
I != End; ++
I) {
297 if (
I->isDebugInstr())
306 if (!KillingInstr && KilledOperand &&
307 I->readsRegister(KilledOperand,
TRI))
315 assert(Added &&
"Must successfully update kill flag");
335 unsigned KilledOperand = 0;
355 if (
MI.isDebugInstr()) {
356 if (
MI.readsRegister(I1DestReg,
TRI))
357 DbgMItoMove.push_back(&
MI);
363 (!
MI.killsRegister(I1UseReg) &&
MI.killsRegister(I1UseReg,
TRI)))
367 if (I1UseReg &&
MI.killsRegister(I1UseReg)) {
368 assert(!KillingInstr &&
"Should only see one killing instruction");
369 KilledOperand = I1UseReg;
377 bool Added =
I1.addRegisterKilled(KilledOperand,
TRI);
379 assert(Added &&
"Must successfully update kill flag");
381 DoInsertAtI1 =
false;
393 if (
MI.isDebugInstr())
401 if (!
Op.isReg() || !
Op.isUse() || !
Op.getReg())
415 unsigned NumInstsToDef = 0;
416 while (&*It != &
MI) {
417 if (!It->isDebugInstr())
425 PotentiallyNewifiableTFR.insert(DefInst);
435 if (!
Op.isDef() || !
Op.getReg())
440 LastDef[*SubRegs] = &
MI;
443 }
else if (
Op.isRegMask()) {
444 for (
unsigned Reg : Hexagon::IntRegsRegClass)
445 if (
Op.clobbersPhysReg(
Reg))
458 bool HasChanged =
false;
462 TRI =
ST->getRegisterInfo();
463 TII =
ST->getInstrInfo();
466 bool OptForSize =
F.hasFnAttribute(Attribute::OptimizeForSize);
473 if (!OptForSize &&
ST->isTinyCore())
478 PotentiallyNewifiableTFR.clear();
479 findPotentialNewifiableTFRs(
MBB);
486 if (
I1.isDebugInstr())
502 bool DoInsertAtI1 =
false;
523 while (I2 !=
I1.getParent()->end() && I2->isDebugInstr())
526 Register I1DestReg =
I1.getOperand(0).getReg();
531 if (I2->modifiesRegister(I1DestReg,
TRI))
542 Register I2DestReg = I2->getOperand(0).getReg();
546 bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
547 bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
548 unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
549 if ((!IsI1LowReg && !IsI2LowReg) || !
isEvenReg(FirstRegIndex))
559 if (isSafeToMoveTogether(
I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
570 bool DoInsertAtI1,
bool OptForSize) {
577 Register I1DestReg =
I1.getOperand(0).getReg();
579 bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
580 unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
584 if (Hexagon::IntRegsRegClass.
contains(LoRegDef)) {
585 SuperRC = &Hexagon::DoubleRegsRegClass;
586 SubLo = Hexagon::isub_lo;
587 }
else if (Hexagon::HvxVRRegClass.
contains(LoRegDef)) {
589 SuperRC = &Hexagon::HvxWRRegClass;
590 SubLo = Hexagon::vsub_lo;
596 assert(DoubleRegDest != 0 &&
"Expect a valid register");
603 bool IsHiReg = HiOperand.
isReg();
604 bool IsLoReg = LoOperand.
isReg();
607 bool IsC64 = OptForSize && LoOperand.
isImm() && HiOperand.
isImm() &&
608 isGreaterThanNBitTFRI<16>(
I1) && isGreaterThanNBitTFRI<16>(I2);
612 if (IsHiReg && IsLoReg)
613 emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
615 emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
617 emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
619 emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
621 emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
625 if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
628 for (
auto NewMI : DbgMItoMove) {
633 BB->splice(InsertPt,
BB, NewMI);
637 I1.eraseFromParent();
642 unsigned DoubleDestReg,
650 "Both operands must be immediate");
652 int64_t V = HiOperand.
getImm();
653 V = (V << 32) | (0x0ffffffffLL & LoOperand.
getImm());
654 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::CONST64), DoubleDestReg)
659 unsigned DoubleDestReg,
667 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A2_combineii), DoubleDestReg)
674 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineii), DoubleDestReg)
683 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A2_combineii), DoubleDestReg)
690 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineii), DoubleDestReg)
698 if (HiOperand.
isJTI()) {
699 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A2_combineii), DoubleDestReg)
704 if (LoOperand.
isJTI()) {
705 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineii), DoubleDestReg)
712 if (HiOperand.
isCPI()) {
713 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A2_combineii), DoubleDestReg)
719 if (LoOperand.
isCPI()) {
720 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineii), DoubleDestReg)
731 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A2_combineii), DoubleDestReg)
739 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineii), DoubleDestReg)
747 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A2_combineii), DoubleDestReg)
753 unsigned DoubleDestReg,
764 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineir), DoubleDestReg)
767 .
addReg(LoReg, LoRegKillFlag);
772 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineir), DoubleDestReg)
775 .
addReg(LoReg, LoRegKillFlag);
779 if (HiOperand.
isJTI()) {
780 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineir), DoubleDestReg)
782 .
addReg(LoReg, LoRegKillFlag);
786 if (HiOperand.
isCPI()) {
787 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineir), DoubleDestReg)
790 .
addReg(LoReg, LoRegKillFlag);
795 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineir), DoubleDestReg)
797 .
addReg(LoReg, LoRegKillFlag);
801 unsigned DoubleDestReg,
812 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineri), DoubleDestReg)
813 .
addReg(HiReg, HiRegKillFlag)
820 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineri), DoubleDestReg)
821 .
addReg(HiReg, HiRegKillFlag)
827 if (LoOperand.
isJTI()) {
828 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineri), DoubleDestReg)
834 if (LoOperand.
isCPI()) {
835 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineri), DoubleDestReg)
844 BuildMI(*
BB, InsertPt,
DL,
TII->get(Hexagon::A4_combineri), DoubleDestReg)
845 .
addReg(HiReg, HiRegKillFlag)
850 unsigned DoubleDestReg,
864 if (Hexagon::DoubleRegsRegClass.
contains(DoubleDestReg)) {
865 NewOpc = Hexagon::A2_combinew;
866 }
else if (Hexagon::HvxWRRegClass.
contains(DoubleDestReg)) {
868 NewOpc = Hexagon::V6_vcombine;
873 .
addReg(HiReg, HiRegKillFlag)
874 .
addReg(LoReg, LoRegKillFlag);
878 return new HexagonCopyToCombine();