41 #define DEBUG_TYPE "ppc-mi-peepholes"
43 STATISTIC(RemoveTOCSave,
"Number of TOC saves removed");
45 "Number of functions with multiple TOC saves that must be kept");
46 STATISTIC(NumTOCSavesInPrologue,
"Number of TOC saves placed in the prologue");
47 STATISTIC(NumEliminatedSExt,
"Number of eliminated sign-extensions");
48 STATISTIC(NumEliminatedZExt,
"Number of eliminated zero-extensions");
49 STATISTIC(NumOptADDLIs,
"Number of optimized ADD instruction fed by LI");
51 "Number of instructions converted to their immediate form");
52 STATISTIC(NumFunctionsEnteredInMIPeephole,
53 "Number of functions entered in PPC MI Peepholes");
55 "Number of fixed-point iterations converting reg-reg instructions "
58 "Number of pairs of rotate left, clear left/right collapsed");
60 "Number of pairs of EXTSW and SLDI combined as EXTSWSLI");
62 "Number of LI(8) reg, 0 that are folded to r0 and removed");
66 cl::desc(
"Iterate to a fixed point when attempting to "
67 "convert reg-reg instructions to reg-imm"));
71 cl::desc(
"Convert eligible reg+reg instructions to reg+imm"));
75 cl::desc(
"enable elimination of sign-extensions"),
80 cl::desc(
"enable elimination of zero-extensions"),
85 cl::desc(
"enable optimization of conditional traps"),
114 bool eliminateRedundantCompare();
115 bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
118 void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
140 "TOC pointer used in a function using PC-Relative addressing!");
143 return simplifyCode();
151 MDT = &getAnalysis<MachineDominatorTree>();
152 MPDT = &getAnalysis<MachinePostDominatorTree>();
153 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
177 unsigned Opcode =
MI->getOpcode();
178 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
179 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec)
180 return MI->getOperand(3).getImm();
182 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
183 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
184 return MI->getOperand(3).getImm();
186 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
187 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
188 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
189 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
190 return 32 +
MI->getOperand(3).getImm();
192 if (Opcode == PPC::ANDI_rec) {
197 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
198 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
199 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
203 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
204 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec)
208 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
209 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
210 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
211 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
214 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
215 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
216 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
217 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
220 if (
TII->isZeroExtended(*
MI))
232 void PPCMIPeephole::UpdateTOCSaves(
234 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
247 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
253 for (
auto &TOCSave : TOCSaves)
254 TOCSave.second =
false;
256 TOCSaves[
MI] =
false;
262 for (
auto &
I : TOCSaves) {
287 PHIs.push_back(RootPHI);
288 unsigned VisitedIndex = 0;
289 while (VisitedIndex < PHIs.size()) {
292 PHIOp != NumOps; PHIOp += 2) {
300 if (Opcode == PPC::COPY) {
305 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
311 if (Opcode != PPC::PHI)
315 PHIs.push_back(Instr);
337 for (
unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps;
339 Register RegOp = PHI->getOperand(PHIOp).getReg();
342 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
343 Opcode == PPC::PHI) &&
344 "Unexpected instruction");
345 if (Opcode == PPC::COPY) {
347 &PPC::ACCRCRegClass &&
348 "Unexpected register class");
349 PHIOps.push_back({PHIInput->
getOperand(1), PHI->getOperand(PHIOp + 1)});
350 }
else if (Opcode == PPC::IMPLICIT_DEF) {
353 TII->get(PPC::IMPLICIT_DEF), AccReg);
355 PHI->getOperand(PHIOp + 1)});
356 }
else if (Opcode == PPC::PHI) {
361 "This PHI node should have already been changed.");
365 PHI->getOperand(PHIOp + 1)});
377 *PHI->getParent(), PHI, PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
378 for (
auto RegMBB : PHIOps)
379 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
380 ChangedPHIMap[PHI] = NewPHI.
getInstr();
385 bool PPCMIPeephole::simplifyCode() {
387 bool TrapOpt =
false;
389 std::map<MachineInstr *, bool> TOCSaves;
391 NumFunctionsEnteredInMIPeephole++;
396 bool SomethingChanged =
false;
398 NumFixedPointIterations++;
399 SomethingChanged =
false;
402 if (
MI.isDebugInstr())
405 if (
TII->convertToImmediateForm(
MI)) {
410 NumConvertedToImmediateForm++;
411 SomethingChanged =
true;
438 if (
MI.isDebugInstr())
442 switch (
MI.getOpcode()) {
470 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
473 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
483 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
485 Register MIDestReg =
MI.getOperand(0).getReg();
489 ++NumLoadImmZeroFoldedAndRemoved;
504 if (
TII->isTOCSaveMI(
MI))
505 UpdateTOCSaves(TOCSaves, &
MI);
512 int Immed =
MI.getOperand(3).getImm();
542 auto isConversionOfLoadAndSplat = [=]() ->
bool {
543 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
549 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
554 if ((Immed == 0 || Immed == 3) &&
555 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
557 "to load-and-splat/copy: ");
560 MI.getOperand(0).getReg())
561 .
add(
MI.getOperand(1));
576 if (DefReg1 != DefReg2) {
580 if (!(FeedReg1 == FeedReg2 &&
585 if (DefImmed == 0 || DefImmed == 3) {
590 MI.getOperand(0).getReg())
591 .
add(
MI.getOperand(1));
599 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
602 MI.getOperand(1).setReg(DefReg1);
603 MI.getOperand(2).setReg(DefReg2);
604 MI.getOperand(3).setImm(3 - Immed);
610 else if (Immed == 2 && DefImmed == 2) {
614 MI.getOperand(0).getReg())
619 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
620 DefOpc == PPC::XXPERMDIs &&
630 MI.getOperand(0).getReg())
631 .
add(
MI.getOperand(1));
645 unsigned MyOpcode =
MI.getOpcode();
646 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
655 auto isConvertOfSplat = [=]() ->
bool {
656 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
662 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
665 bool AlreadySplat = (MyOpcode == DefOpcode) ||
666 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
667 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
668 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
669 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
670 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
671 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
678 MI.getOperand(0).getReg())
679 .
add(
MI.getOperand(OpNo));
685 if (DefOpcode == PPC::XXSLDWI) {
691 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
692 if (ShiftOp1 == ShiftOp2) {
693 unsigned NewElem = (SplatImm + ShiftImm) & 0
x3;
701 <<
" to " << NewElem <<
" in instruction: ");
703 MI.getOperand(1).setReg(ShiftOp1);
704 MI.getOperand(2).setImm(NewElem);
709 case PPC::XVCVDPSP: {
736 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
738 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
741 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
742 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
744 for (
int i = 0,
e =
Use.getNumOperands();
i <
e; ++
i)
745 if (
Use.getOperand(
i).isReg() &&
746 Use.getOperand(
i).getReg() == FRSPDefines)
747 Use.getOperand(
i).setReg(ConvReg1);
754 RoundInstr->eraseFromParent();
762 removeFRSPIfPossible(P1);
763 removeFRSPIfPossible(
P2);
766 removeFRSPIfPossible(P1);
772 case PPC::EXTSH8_32_64: {
774 Register NarrowReg =
MI.getOperand(1).getReg();
785 auto is64Bit = [] (
unsigned Opcode) {
786 return Opcode == PPC::EXTSH8;
788 auto isXForm = [] (
unsigned Opcode) {
789 return Opcode == PPC::LHZX;
791 auto getSextLoadOp = [] (
bool is64Bit,
bool isXForm) {
793 if (isXForm)
return PPC::LHAX8;
794 else return PPC::LHA8;
796 if (isXForm)
return PPC::LHAX;
797 else return PPC::LHA;
799 unsigned Opc = getSextLoadOp(
is64Bit(
MI.getOpcode()),
816 case PPC::EXTSW_32_64: {
818 Register NarrowReg =
MI.getOperand(1).getReg();
829 auto is64Bit = [] (
unsigned Opcode) {
830 return Opcode == PPC::EXTSW || Opcode == PPC::EXTSW_32_64;
832 auto isXForm = [] (
unsigned Opcode) {
833 return Opcode == PPC::LWZX;
835 auto getSextLoadOp = [] (
bool is64Bit,
bool isXForm) {
837 if (isXForm)
return PPC::LWAX;
838 else return PPC::LWA;
840 if (isXForm)
return PPC::LWAX_32;
841 else return PPC::LWA_32;
843 unsigned Opc = getSextLoadOp(
is64Bit(
MI.getOpcode()),
855 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
856 TII->isSignExtended(*SrcMI)) {
861 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
865 MI.getOperand(0).getReg())
884 if (
MI.getOperand(2).getImm() != 0)
892 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
899 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
902 if (SubRegMI->
getOpcode() == PPC::COPY) {
908 unsigned KnownZeroCount = getKnownLeadingZeroCount(SrcMI,
TII);
909 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
912 MI.getOperand(0).getReg())
928 assert(PhiOp &&
"Invalid Operand!");
931 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
937 assert(PhiOp &&
"Invalid Operand!");
938 assert(DominatorOp &&
"Invalid Operand!");
959 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
961 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
968 ? &PPC::G8RC_and_G8RC_NOX0RegClass
969 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1002 MI.getOperand(0).getReg())
1011 combineSEXTAndSHL(
MI, ToErase);
1015 case PPC::RLWINM_rec:
1017 case PPC::RLWINM8_rec: {
1020 ++NumRotatesCollapsed;
1032 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1035 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1038 if (!IsOperand2Immediate &&
1039 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1043 auto ImmOperand0 =
MI.getOperand(0).getImm();
1045 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1050 if ((ImmOperand0 == 31) ||
1051 ((ImmOperand0 & 0x10) &&
1052 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1053 ((ImmOperand0 & 0x8) &&
1054 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1055 ((ImmOperand0 & 0
x2) &&
1057 ((ImmOperand0 & 0x1) &&
1059 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1083 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1086 NumTOCSavesInPrologue++;
1101 static bool isSupportedCmpOp(
unsigned opCode) {
1102 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1103 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1104 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1105 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1108 static bool is64bitCmpOp(
unsigned opCode) {
1109 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1110 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1113 static bool isSignedCmpOp(
unsigned opCode) {
1114 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1115 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1118 static unsigned getSignedCmpOpCode(
unsigned opCode) {
1119 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1120 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1121 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1122 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1130 bool SignedCmp = isSignedCmpOp(CMPI->
getOpcode());
1131 if ((!SignedCmp &&
Imm == 0) || (SignedCmp &&
Imm == 0x8000))
1149 bool SignedCmp = isSignedCmpOp(CMPI->
getOpcode());
1150 if ((!SignedCmp &&
Imm == 0xFFFF) || (SignedCmp &&
Imm == 0x7FFF))
1165 static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1181 unsigned SrcReg =
Reg;
1183 unsigned NextReg = SrcReg;
1186 NextReg = getIncomingRegForBlock(Inst, BB1);
1205 auto BII =
BB.getFirstInstrTerminator();
1209 if (
BB.succ_size() == 2 &&
1210 BII !=
BB.instr_end() &&
1211 (*BII).getOpcode() == PPC::BCC &&
1212 (*BII).getOperand(1).isReg()) {
1214 Register CndReg = (*BII).getOperand(1).getReg();
1238 return BB.succ_size() == 1;
1241 if (!isEligibleBB(
MBB))
1245 if (NumPredBBs == 1) {
1247 if (isEligibleBB(*TmpMBB)) {
1249 MBBtoMoveCmp =
nullptr;
1253 else if (NumPredBBs == 2) {
1261 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1266 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1277 for (
int I = 1;
I <= 2;
I++)
1285 MBBtoMoveCmp = Pred2MBB;
1296 bool PPCMIPeephole::eliminateRedundantTOCSaves(
1297 std::map<MachineInstr *, bool> &TOCSaves) {
1300 for (
auto TOCSave : TOCSaves) {
1301 if (!TOCSave.second) {
1302 TOCSave.first->eraseFromParent();
1338 bool PPCMIPeephole::eliminateRedundantCompare() {
1371 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1379 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1383 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1384 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1388 unsigned NewOpCode = 0;
1389 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1391 bool SwapOperands =
false;
1403 if (!
I->getOperand(2).isImm())
1405 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1409 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1412 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1422 nullptr,
nullptr,
MRI);
1424 nullptr,
nullptr,
MRI);
1430 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1433 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1440 SwapOperands =
true;
1448 nullptr,
nullptr,
MRI);
1451 if (Cmp1Operand1 != Cmp2Operand1)
1459 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1460 int Diff = Imm1 - Imm2;
1461 if (Diff < -2 || Diff > 2)
1464 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1465 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1466 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1467 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1469 if (PredToInc2 && PredToDec1) {
1470 NewPredicate2 = PredToInc2;
1471 NewPredicate1 = PredToDec1;
1476 else if (Diff == 1) {
1479 NewPredicate2 = PredToInc2;
1481 else if (PredToDec1) {
1483 NewPredicate1 = PredToDec1;
1486 else if (Diff == -1) {
1489 NewPredicate2 = PredToDec2;
1491 else if (PredToInc1) {
1493 NewPredicate1 = PredToInc1;
1496 else if (Diff == -2) {
1497 if (PredToDec2 && PredToInc1) {
1498 NewPredicate2 = PredToDec2;
1499 NewPredicate1 = PredToInc1;
1511 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1518 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1521 if (NewPredicate1) {
1524 if (NewPredicate2) {
1531 if (IsPartiallyRedundant) {
1543 for (
int I = 1;
I <= 2;
I++) {
1550 "We cannot support if an operand comes from this BB.");
1551 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1561 TII->get(PPC::PHI), NewVReg)
1578 if (IsPartiallyRedundant) {
1581 <<
" to handle partial redundancy.\n");
1594 bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI) {
1595 if (
MI.getOpcode() != PPC::RLDICR)
1620 if (NewMB > 63 || NewSH > 63)
1629 if ((63 - NewSH) != MEMI)
1636 MI.setDesc(
TII->get(PPC::RLDIC));
1638 MI.getOperand(2).setImm(NewSH);
1639 MI.getOperand(3).setImm(NewMB);
1645 NumRotatesCollapsed++;
1649 "Not expecting an implicit def with this instr.");
1668 if (
MI.getOpcode() != PPC::RLDICR)
1674 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1683 if (SHMI + MEMI != 63)
1702 "EXTSW's second operand should be a register");
1713 :
TII->get(PPC::EXTSWSLI_32_64),
1714 MI.getOperand(0).getReg())
1721 ++NumEXTSWAndSLDICombined;
1731 "PowerPC MI Peephole Optimization",
false,
false)
1738 char PPCMIPeephole::
ID = 0;