41#define DEBUG_TYPE "ppc-mi-peepholes"
43STATISTIC(RemoveTOCSave,
"Number of TOC saves removed");
45 "Number of functions with multiple TOC saves that must be kept");
46STATISTIC(NumTOCSavesInPrologue,
"Number of TOC saves placed in the prologue");
47STATISTIC(NumEliminatedSExt,
"Number of eliminated sign-extensions");
48STATISTIC(NumEliminatedZExt,
"Number of eliminated zero-extensions");
49STATISTIC(NumOptADDLIs,
"Number of optimized ADD instruction fed by LI");
51 "Number of instructions converted to their immediate form");
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>();
162 assert(Op &&
"Invalid Operand!");
167 if (!
Reg.isVirtual())
170 return MRI->getVRegDef(Reg);
175static unsigned getKnownLeadingZeroCount(
const unsigned Reg,
179 unsigned Opcode =
MI->getOpcode();
180 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
181 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec)
182 return MI->getOperand(3).getImm();
184 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
185 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
186 return MI->getOperand(3).getImm();
188 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
189 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
190 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
191 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
192 return 32 +
MI->getOperand(3).getImm();
194 if (Opcode == PPC::ANDI_rec) {
199 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
200 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
201 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
205 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
206 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec)
210 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
211 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
212 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
213 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
216 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
217 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
218 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
219 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
222 if (
TII->isZeroExtended(Reg,
MRI))
234void PPCMIPeephole::UpdateTOCSaves(
236 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
249 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
255 for (
auto &TOCSave : TOCSaves)
256 TOCSave.second =
false;
258 TOCSaves[
MI] =
false;
264 for (
auto &
I : TOCSaves) {
290 unsigned VisitedIndex = 0;
291 while (VisitedIndex < PHIs.
size()) {
294 PHIOp != NumOps; PHIOp += 2) {
302 if (Opcode == PPC::COPY) {
304 if (!
Reg.isVirtual() ||
MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
306 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
312 if (Opcode != PPC::PHI)
338 for (
unsigned PHIOp = 1, NumOps =
PHI->getNumOperands(); PHIOp != NumOps;
343 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
344 Opcode == PPC::PHI) &&
345 "Unexpected instruction");
346 if (Opcode == PPC::COPY) {
348 &PPC::ACCRCRegClass &&
349 "Unexpected register class");
351 }
else if (Opcode == PPC::IMPLICIT_DEF) {
352 Register AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
354 TII->get(PPC::IMPLICIT_DEF), AccReg);
356 PHI->getOperand(PHIOp + 1)});
357 }
else if (Opcode == PPC::PHI) {
362 "This PHI node should have already been changed.");
366 PHI->getOperand(PHIOp + 1)});
376 AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
378 *
PHI->getParent(),
PHI,
PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
379 for (
auto RegMBB : PHIOps)
380 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
390bool PPCMIPeephole::simplifyCode() {
392 bool TrapOpt =
false;
394 std::map<MachineInstr *, bool> TOCSaves;
396 NumFunctionsEnteredInMIPeephole++;
401 bool SomethingChanged =
false;
403 NumFixedPointIterations++;
404 SomethingChanged =
false;
407 if (
MI.isDebugInstr())
410 if (
TII->convertToImmediateForm(
MI)) {
415 NumConvertedToImmediateForm++;
416 SomethingChanged =
true;
445 if (
MI.isDebugInstr())
449 switch (
MI.getOpcode()) {
456 if (!Src.isVirtual() || !Dst.isVirtual())
458 if (
MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
459 MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
476 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
479 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
489 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
491 Register MIDestReg =
MI.getOperand(0).getReg();
494 if (
MRI->use_nodbg_empty(MIDestReg)) {
495 ++NumLoadImmZeroFoldedAndRemoved;
510 if (
TII->isTOCSaveMI(
MI))
511 UpdateTOCSaves(TOCSaves, &
MI);
514 case PPC::XXPERMDI: {
518 int Immed =
MI.getOperand(3).getImm();
530 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
532 TRI->lookThruCopyLike(
MI.getOperand(2).getReg(),
MRI);
534 if (!(TrueReg1 == TrueReg2 && TrueReg1.
isVirtual()))
548 auto isConversionOfLoadAndSplat = [=]() ->
bool {
549 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
555 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
560 if ((Immed == 0 || Immed == 3) &&
561 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
563 "to load-and-splat/copy: ");
566 MI.getOperand(0).getReg())
567 .
add(
MI.getOperand(1));
574 if (DefOpc == PPC::XXPERMDI) {
582 if (DefReg1 != DefReg2) {
586 if (!(FeedReg1 == FeedReg2 && FeedReg1.
isVirtual()))
590 if (DefImmed == 0 || DefImmed == 3) {
595 MI.getOperand(0).getReg())
596 .
add(
MI.getOperand(1));
604 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
607 MI.getOperand(1).setReg(DefReg1);
608 MI.getOperand(2).setReg(DefReg2);
609 MI.getOperand(3).setImm(3 - Immed);
615 else if (Immed == 2 && DefImmed == 2) {
619 MI.getOperand(0).getReg())
624 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
625 DefOpc == PPC::XXPERMDIs &&
635 MI.getOperand(0).getReg())
636 .
add(
MI.getOperand(1));
644 }
else if (Immed == 2 &&
645 (DefOpc == PPC::VSPLTB || DefOpc == PPC::VSPLTH ||
646 DefOpc == PPC::VSPLTW || DefOpc == PPC::XXSPLTW)) {
651 "copy(vsplt[b|h|w]|xxspltw): ");
654 MI.getOperand(0).getReg())
655 .
add(
MI.getOperand(1));
662 unsigned MyOpcode =
MI.getOpcode();
663 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
665 TRI->lookThruCopyLike(
MI.getOperand(OpNo).getReg(),
MRI);
672 auto isConvertOfSplat = [=]() ->
bool {
673 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
679 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
682 bool AlreadySplat = (MyOpcode == DefOpcode) ||
683 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
684 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
685 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
686 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
687 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
688 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
695 MI.getOperand(0).getReg())
696 .
add(
MI.getOperand(OpNo));
702 if (DefOpcode == PPC::XXSLDWI) {
708 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
709 if (ShiftOp1 == ShiftOp2) {
710 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
711 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
718 <<
" to " << NewElem <<
" in instruction: ");
720 MI.getOperand(1).setReg(ShiftOp1);
721 MI.getOperand(2).setImm(NewElem);
726 case PPC::XVCVDPSP: {
729 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
752 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
753 unsigned Opc = RoundInstr->getOpcode();
754 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
755 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
757 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
758 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
760 for (
int i = 0, e =
Use.getNumOperands(); i <
e; ++i)
761 if (
Use.getOperand(i).isReg() &&
762 Use.getOperand(i).getReg() == FRSPDefines)
763 Use.getOperand(i).setReg(ConvReg1);
770 RoundInstr->eraseFromParent();
778 removeFRSPIfPossible(P1);
779 removeFRSPIfPossible(P2);
782 removeFRSPIfPossible(P1);
788 case PPC::EXTSH8_32_64: {
790 Register NarrowReg =
MI.getOperand(1).getReg();
798 if (SrcOpcode == PPC::LHZ || SrcOpcode == PPC::LHZX) {
805 unsigned Opc = PPC::LHA;
806 bool SourceIsXForm = SrcOpcode == PPC::LHZX;
807 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSH8 ||
808 MI.getOpcode() == PPC::EXTSH8_32_64;
810 if (SourceIsXForm && MIIs64Bit)
812 else if (SourceIsXForm && !MIIs64Bit)
832 case PPC::EXTSW_32_64: {
834 Register NarrowReg =
MI.getOperand(1).getReg();
842 if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) {
850 bool IsWordAligned =
false;
856 IsWordAligned =
true;
860 IsWordAligned =
true;
867 unsigned Opc = PPC::LWA_32;
868 bool SourceIsXForm = SrcOpcode == PPC::LWZX;
869 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSW ||
870 MI.getOpcode() == PPC::EXTSW_32_64;
872 if (SourceIsXForm && MIIs64Bit)
874 else if (SourceIsXForm && !MIIs64Bit)
879 if (!IsWordAligned && (Opc == PPC::LWA || Opc == PPC::LWA_32))
892 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
893 TII->isSignExtended(NarrowReg,
MRI)) {
898 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
902 MI.getOperand(0).getReg())
921 if (
MI.getOperand(2).getImm() != 0)
929 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
936 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
939 if (SubRegMI->
getOpcode() == PPC::COPY) {
942 SrcMI =
MRI->getVRegDef(CopyReg);
947 unsigned KnownZeroCount =
949 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
952 MI.getOperand(0).getReg())
968 assert(PhiOp &&
"Invalid Operand!");
971 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
977 assert(PhiOp &&
"Invalid Operand!");
978 assert(DominatorOp &&
"Invalid Operand!");
999 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
1001 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
1008 ? &PPC::G8RC_and_G8RC_NOX0RegClass
1009 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1010 MRI->setRegClass(DominatorReg, TRC);
1042 MI.getOperand(0).getReg())
1051 combineSEXTAndSHL(
MI, ToErase);
1055 case PPC::RLWINM_rec:
1057 case PPC::RLWINM8_rec: {
1060 ++NumRotatesCollapsed;
1072 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1075 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1078 if (!IsOperand2Immediate &&
1079 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1083 auto ImmOperand0 =
MI.getOperand(0).getImm();
1085 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1090 if ((ImmOperand0 == 31) ||
1091 ((ImmOperand0 & 0x10) &&
1092 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1093 ((ImmOperand0 & 0x8) &&
1094 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1095 ((ImmOperand0 & 0x2) &&
1097 ((ImmOperand0 & 0x1) &&
1099 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1123 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1126 NumTOCSavesInPrologue++;
1141static bool isSupportedCmpOp(
unsigned opCode) {
1142 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1143 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1144 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1145 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1148static bool is64bitCmpOp(
unsigned opCode) {
1149 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1150 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1153static bool isSignedCmpOp(
unsigned opCode) {
1154 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1155 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1158static unsigned getSignedCmpOpCode(
unsigned opCode) {
1159 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1160 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1161 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1162 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1170 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1171 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1189 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1190 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1205static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1221 unsigned SrcReg =
Reg;
1223 unsigned NextReg = SrcReg;
1226 NextReg = getIncomingRegForBlock(Inst, BB1);
1245 auto BII = BB.getFirstInstrTerminator();
1249 if (BB.succ_size() == 2 &&
1250 BII != BB.instr_end() &&
1251 (*BII).getOpcode() == PPC::BCC &&
1252 (*BII).getOperand(1).isReg()) {
1254 Register CndReg = (*BII).getOperand(1).getReg();
1255 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1260 if (
CMPI->getParent() != &BB)
1278 return BB.succ_size() == 1;
1281 if (!isEligibleBB(
MBB))
1285 if (NumPredBBs == 1) {
1287 if (isEligibleBB(*TmpMBB)) {
1289 MBBtoMoveCmp =
nullptr;
1293 else if (NumPredBBs == 2) {
1301 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1306 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1317 for (
int I = 1;
I <= 2;
I++)
1318 if (
CMPI->getOperand(
I).isReg()) {
1325 MBBtoMoveCmp = Pred2MBB;
1336bool PPCMIPeephole::eliminateRedundantTOCSaves(
1337 std::map<MachineInstr *, bool> &TOCSaves) {
1340 for (
auto TOCSave : TOCSaves) {
1341 if (!TOCSave.second) {
1342 TOCSave.first->eraseFromParent();
1378bool PPCMIPeephole::eliminateRedundantCompare() {
1411 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1419 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1423 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1424 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1428 unsigned NewOpCode = 0;
1429 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1431 bool SwapOperands =
false;
1443 if (!
I->getOperand(2).isImm())
1445 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1449 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1452 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1462 nullptr,
nullptr,
MRI);
1464 nullptr,
nullptr,
MRI);
1470 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1473 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1480 SwapOperands =
true;
1488 nullptr,
nullptr,
MRI);
1491 if (Cmp1Operand1 != Cmp2Operand1)
1499 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1500 int Diff = Imm1 - Imm2;
1501 if (Diff < -2 || Diff > 2)
1504 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1505 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1506 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1507 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1509 if (PredToInc2 && PredToDec1) {
1510 NewPredicate2 = PredToInc2;
1511 NewPredicate1 = PredToDec1;
1516 else if (Diff == 1) {
1519 NewPredicate2 = PredToInc2;
1521 else if (PredToDec1) {
1523 NewPredicate1 = PredToDec1;
1526 else if (Diff == -1) {
1529 NewPredicate2 = PredToDec2;
1531 else if (PredToInc1) {
1533 NewPredicate1 = PredToInc1;
1536 else if (Diff == -2) {
1537 if (PredToDec2 && PredToInc1) {
1538 NewPredicate2 = PredToDec2;
1539 NewPredicate1 = PredToInc1;
1551 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1558 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1561 if (NewPredicate1) {
1564 if (NewPredicate2) {
1571 if (IsPartiallyRedundant) {
1583 for (
int I = 1;
I <= 2;
I++) {
1590 "We cannot support if an operand comes from this BB.");
1591 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1599 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1601 TII->get(PPC::PHI), NewVReg)
1618 if (IsPartiallyRedundant) {
1621 <<
" to handle partial redundancy.\n");
1634bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI) {
1635 if (
MI.getOpcode() != PPC::RLDICR)
1660 if (NewMB > 63 || NewSH > 63)
1669 if ((63 - NewSH) != MEMI)
1676 MI.setDesc(
TII->get(PPC::RLDIC));
1678 MI.getOperand(2).setImm(NewSH);
1679 MI.getOperand(3).setImm(NewMB);
1685 NumRotatesCollapsed++;
1687 if (
MRI->use_nodbg_empty(SrcReg)) {
1689 "Not expecting an implicit def with this instr.");
1708 if (
MI.getOpcode() != PPC::RLDICR)
1714 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1723 if (SHMI + MEMI != 63)
1737 if (!
MRI->hasOneNonDBGUse(SrcReg))
1742 "EXTSW's second operand should be a register");
1752 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
1753 :
TII->get(PPC::EXTSWSLI_32_64),
1754 MI.getOperand(0).getReg())
1761 ++NumEXTSWAndSLDICombined;
1771 "PowerPC MI Peephole Optimization",
false,
false)
1778char PPCMIPeephole::
ID = 0;
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
PowerPC MI Peephole Optimization
static cl::opt< bool > EnableZExtElimination("ppc-eliminate-zeroext", cl::desc("enable elimination of zero-extensions"), cl::init(true), cl::Hidden)
static cl::opt< bool > FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true), cl::desc("Iterate to a fixed point when attempting to " "convert reg-reg instructions to reg-imm"))
static cl::opt< bool > EnableTrapOptimization("ppc-opt-conditional-trap", cl::desc("enable optimization of conditional traps"), cl::init(false), cl::Hidden)
static cl::opt< bool > ConvertRegReg("ppc-convert-rr-to-ri", cl::Hidden, cl::init(true), cl::desc("Convert eligible reg+reg instructions to reg+imm"))
static cl::opt< bool > EnableSExtElimination("ppc-eliminate-signext", cl::desc("enable elimination of sign-extensions"), cl::init(true), cl::Hidden)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
unsigned pred_size() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
pred_iterator pred_begin()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
std::vector< MachineBasicBlock * >::iterator pred_iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
uint64_t getEntryFreq() const
Divide a block's BlockFrequency::getFrequency() value by this value to obtain the entry block - relat...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
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
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasImplicitDef() const
Returns true if the instruction has implicit definition.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setMustSaveTOC(bool U)
bool isUsingPCRelativeCalls() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Wrapper class representing virtual and physical registers.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
unsigned getPredicateCondition(Predicate Opcode)
Return the condition without hint bits.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
unsigned getPredicateHint(Predicate Opcode)
Return the hint bits of the predicate.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void initializePPCMIPeepholePass(PassRegistry &)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
@ Keep
No function return thunk.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
FunctionPass * createPPCMIPeepholePass()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.