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 (Opcode == PPC::AND || Opcode == PPC::AND8 || Opcode == PPC::AND_rec ||
223 Opcode == PPC::AND8_rec)
225 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
226 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
228 if (Opcode == PPC::OR || Opcode == PPC::OR8 || Opcode == PPC::XOR ||
229 Opcode == PPC::XOR8 || Opcode == PPC::OR_rec ||
230 Opcode == PPC::OR8_rec || Opcode == PPC::XOR_rec ||
231 Opcode == PPC::XOR8_rec)
233 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
234 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
236 if (
TII->isZeroExtended(Reg,
MRI))
248void PPCMIPeephole::UpdateTOCSaves(
250 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
263 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
269 for (
auto &TOCSave : TOCSaves)
270 TOCSave.second =
false;
272 TOCSaves[
MI] =
false;
278 for (
auto &
I : TOCSaves) {
304 unsigned VisitedIndex = 0;
305 while (VisitedIndex < PHIs.
size()) {
308 PHIOp != NumOps; PHIOp += 2) {
316 if (Opcode == PPC::COPY) {
318 if (!
Reg.isVirtual() ||
MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
320 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
326 if (Opcode != PPC::PHI)
352 for (
unsigned PHIOp = 1, NumOps =
PHI->getNumOperands(); PHIOp != NumOps;
357 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
358 Opcode == PPC::PHI) &&
359 "Unexpected instruction");
360 if (Opcode == PPC::COPY) {
362 &PPC::ACCRCRegClass &&
363 "Unexpected register class");
365 }
else if (Opcode == PPC::IMPLICIT_DEF) {
366 Register AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
368 TII->get(PPC::IMPLICIT_DEF), AccReg);
370 PHI->getOperand(PHIOp + 1)});
371 }
else if (Opcode == PPC::PHI) {
376 "This PHI node should have already been changed.");
380 PHI->getOperand(PHIOp + 1)});
390 AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
392 *
PHI->getParent(),
PHI,
PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
393 for (
auto RegMBB : PHIOps)
394 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
404bool PPCMIPeephole::simplifyCode() {
406 bool TrapOpt =
false;
408 std::map<MachineInstr *, bool> TOCSaves;
410 NumFunctionsEnteredInMIPeephole++;
415 bool SomethingChanged =
false;
417 NumFixedPointIterations++;
418 SomethingChanged =
false;
421 if (
MI.isDebugInstr())
424 if (
TII->convertToImmediateForm(
MI)) {
429 NumConvertedToImmediateForm++;
430 SomethingChanged =
true;
459 if (
MI.isDebugInstr())
463 switch (
MI.getOpcode()) {
470 if (!Src.isVirtual() || !Dst.isVirtual())
472 if (
MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
473 MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
490 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
493 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
503 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
505 Register MIDestReg =
MI.getOperand(0).getReg();
508 if (
MRI->use_nodbg_empty(MIDestReg)) {
509 ++NumLoadImmZeroFoldedAndRemoved;
524 if (
TII->isTOCSaveMI(
MI))
525 UpdateTOCSaves(TOCSaves, &
MI);
528 case PPC::XXPERMDI: {
532 int Immed =
MI.getOperand(3).getImm();
544 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
546 TRI->lookThruCopyLike(
MI.getOperand(2).getReg(),
MRI);
548 if (!(TrueReg1 == TrueReg2 && TrueReg1.
isVirtual()))
562 auto isConversionOfLoadAndSplat = [=]() ->
bool {
563 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
569 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
574 if ((Immed == 0 || Immed == 3) &&
575 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
577 "to load-and-splat/copy: ");
580 MI.getOperand(0).getReg())
581 .
add(
MI.getOperand(1));
588 if (DefOpc == PPC::XXPERMDI) {
596 if (DefReg1 != DefReg2) {
600 if (!(FeedReg1 == FeedReg2 && FeedReg1.
isVirtual()))
604 if (DefImmed == 0 || DefImmed == 3) {
609 MI.getOperand(0).getReg())
610 .
add(
MI.getOperand(1));
618 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
621 MI.getOperand(1).setReg(DefReg1);
622 MI.getOperand(2).setReg(DefReg2);
623 MI.getOperand(3).setImm(3 - Immed);
629 else if (Immed == 2 && DefImmed == 2) {
633 MI.getOperand(0).getReg())
638 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
639 DefOpc == PPC::XXPERMDIs &&
649 MI.getOperand(0).getReg())
650 .
add(
MI.getOperand(1));
658 }
else if (Immed == 2 &&
659 (DefOpc == PPC::VSPLTB || DefOpc == PPC::VSPLTH ||
660 DefOpc == PPC::VSPLTW || DefOpc == PPC::XXSPLTW)) {
665 "copy(vsplt[b|h|w]|xxspltw): ");
668 MI.getOperand(0).getReg())
669 .
add(
MI.getOperand(1));
670 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
671 TII->isLoadFromConstantPool(
DefMI)) {
673 if (
C &&
C->getType()->isVectorTy() &&
C->getSplatValue()) {
677 <<
"Optimizing swap(splat pattern from constant-pool) "
678 "=> copy(splat pattern from constant-pool): ");
681 MI.getOperand(0).getReg())
682 .
add(
MI.getOperand(1));
690 unsigned MyOpcode =
MI.getOpcode();
691 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
693 TRI->lookThruCopyLike(
MI.getOperand(OpNo).getReg(),
MRI);
700 auto isConvertOfSplat = [=]() ->
bool {
701 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
707 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
710 bool AlreadySplat = (MyOpcode == DefOpcode) ||
711 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
712 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
713 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
714 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
715 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
716 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
723 MI.getOperand(0).getReg())
724 .
add(
MI.getOperand(OpNo));
730 if (DefOpcode == PPC::XXSLDWI) {
736 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
737 if (ShiftOp1 == ShiftOp2) {
738 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
739 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
746 <<
" to " << NewElem <<
" in instruction: ");
748 MI.getOperand(1).setReg(ShiftOp1);
749 MI.getOperand(2).setImm(NewElem);
754 case PPC::XVCVDPSP: {
757 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
780 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
781 unsigned Opc = RoundInstr->getOpcode();
782 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
783 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
785 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
786 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
788 for (
int i = 0, e =
Use.getNumOperands(); i <
e; ++i)
789 if (
Use.getOperand(i).isReg() &&
790 Use.getOperand(i).getReg() == FRSPDefines)
791 Use.getOperand(i).setReg(ConvReg1);
798 RoundInstr->eraseFromParent();
806 removeFRSPIfPossible(P1);
807 removeFRSPIfPossible(P2);
810 removeFRSPIfPossible(P1);
816 case PPC::EXTSH8_32_64: {
818 Register NarrowReg =
MI.getOperand(1).getReg();
826 if (SrcOpcode == PPC::LHZ || SrcOpcode == PPC::LHZX) {
833 unsigned Opc = PPC::LHA;
834 bool SourceIsXForm = SrcOpcode == PPC::LHZX;
835 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSH8 ||
836 MI.getOpcode() == PPC::EXTSH8_32_64;
838 if (SourceIsXForm && MIIs64Bit)
840 else if (SourceIsXForm && !MIIs64Bit)
860 case PPC::EXTSW_32_64: {
862 Register NarrowReg =
MI.getOperand(1).getReg();
870 if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) {
878 bool IsWordAligned =
false;
884 IsWordAligned =
true;
888 IsWordAligned =
true;
895 unsigned Opc = PPC::LWA_32;
896 bool SourceIsXForm = SrcOpcode == PPC::LWZX;
897 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSW ||
898 MI.getOpcode() == PPC::EXTSW_32_64;
900 if (SourceIsXForm && MIIs64Bit)
902 else if (SourceIsXForm && !MIIs64Bit)
907 if (!IsWordAligned && (Opc == PPC::LWA || Opc == PPC::LWA_32))
920 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
921 TII->isSignExtended(NarrowReg,
MRI)) {
926 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
930 MI.getOperand(0).getReg())
949 if (
MI.getOperand(2).getImm() != 0)
957 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
964 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
967 if (SubRegMI->
getOpcode() == PPC::COPY) {
970 SrcMI =
MRI->getVRegDef(CopyReg);
975 unsigned KnownZeroCount =
977 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
980 MI.getOperand(0).getReg())
996 assert(PhiOp &&
"Invalid Operand!");
999 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
1005 assert(PhiOp &&
"Invalid Operand!");
1006 assert(DominatorOp &&
"Invalid Operand!");
1027 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
1029 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
1036 ? &PPC::G8RC_and_G8RC_NOX0RegClass
1037 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1038 MRI->setRegClass(DominatorReg, TRC);
1070 MI.getOperand(0).getReg())
1079 combineSEXTAndSHL(
MI, ToErase);
1083 case PPC::RLWINM_rec:
1085 case PPC::RLWINM8_rec: {
1088 ++NumRotatesCollapsed;
1100 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1103 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1106 if (!IsOperand2Immediate &&
1107 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1111 auto ImmOperand0 =
MI.getOperand(0).getImm();
1113 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1118 if ((ImmOperand0 == 31) ||
1119 ((ImmOperand0 & 0x10) &&
1120 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1121 ((ImmOperand0 & 0x8) &&
1122 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1123 ((ImmOperand0 & 0x2) &&
1125 ((ImmOperand0 & 0x1) &&
1127 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1151 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1154 NumTOCSavesInPrologue++;
1169static bool isSupportedCmpOp(
unsigned opCode) {
1170 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1171 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1172 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1173 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1176static bool is64bitCmpOp(
unsigned opCode) {
1177 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1178 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1181static bool isSignedCmpOp(
unsigned opCode) {
1182 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1183 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1186static unsigned getSignedCmpOpCode(
unsigned opCode) {
1187 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1188 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1189 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1190 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1198 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1199 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1217 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1218 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1233static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1249 unsigned SrcReg =
Reg;
1251 unsigned NextReg = SrcReg;
1254 NextReg = getIncomingRegForBlock(Inst, BB1);
1273 auto BII = BB.getFirstInstrTerminator();
1277 if (BB.succ_size() == 2 &&
1278 BII != BB.instr_end() &&
1279 (*BII).getOpcode() == PPC::BCC &&
1280 (*BII).getOperand(1).isReg()) {
1282 Register CndReg = (*BII).getOperand(1).getReg();
1283 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1288 if (
CMPI->getParent() != &BB)
1306 return BB.succ_size() == 1;
1309 if (!isEligibleBB(
MBB))
1313 if (NumPredBBs == 1) {
1315 if (isEligibleBB(*TmpMBB)) {
1317 MBBtoMoveCmp =
nullptr;
1321 else if (NumPredBBs == 2) {
1329 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1334 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1340 if (Pred1MBB == &
MBB)
1348 for (
int I = 1;
I <= 2;
I++)
1349 if (
CMPI->getOperand(
I).isReg()) {
1356 MBBtoMoveCmp = Pred2MBB;
1367bool PPCMIPeephole::eliminateRedundantTOCSaves(
1368 std::map<MachineInstr *, bool> &TOCSaves) {
1371 for (
auto TOCSave : TOCSaves) {
1372 if (!TOCSave.second) {
1373 TOCSave.first->eraseFromParent();
1409bool PPCMIPeephole::eliminateRedundantCompare() {
1442 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1450 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1454 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1455 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1459 unsigned NewOpCode = 0;
1460 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1462 bool SwapOperands =
false;
1474 if (!
I->getOperand(2).isImm())
1476 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1480 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1483 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1493 nullptr,
nullptr,
MRI);
1495 nullptr,
nullptr,
MRI);
1501 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1504 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1511 SwapOperands =
true;
1519 nullptr,
nullptr,
MRI);
1522 if (Cmp1Operand1 != Cmp2Operand1)
1530 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1531 int Diff = Imm1 - Imm2;
1532 if (Diff < -2 || Diff > 2)
1535 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1536 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1537 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1538 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1540 if (PredToInc2 && PredToDec1) {
1541 NewPredicate2 = PredToInc2;
1542 NewPredicate1 = PredToDec1;
1547 else if (Diff == 1) {
1550 NewPredicate2 = PredToInc2;
1552 else if (PredToDec1) {
1554 NewPredicate1 = PredToDec1;
1557 else if (Diff == -1) {
1560 NewPredicate2 = PredToDec2;
1562 else if (PredToInc1) {
1564 NewPredicate1 = PredToInc1;
1567 else if (Diff == -2) {
1568 if (PredToDec2 && PredToInc1) {
1569 NewPredicate2 = PredToDec2;
1570 NewPredicate1 = PredToInc1;
1582 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1589 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1592 if (NewPredicate1) {
1595 if (NewPredicate2) {
1602 if (IsPartiallyRedundant) {
1614 for (
int I = 1;
I <= 2;
I++) {
1621 "We cannot support if an operand comes from this BB.");
1622 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1630 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1632 TII->get(PPC::PHI), NewVReg)
1649 if (IsPartiallyRedundant) {
1652 <<
" to handle partial redundancy.\n");
1665bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI) {
1666 if (
MI.getOpcode() != PPC::RLDICR)
1691 if (NewMB > 63 || NewSH > 63)
1700 if ((63 - NewSH) != MEMI)
1707 MI.setDesc(
TII->get(PPC::RLDIC));
1709 MI.getOperand(2).setImm(NewSH);
1710 MI.getOperand(3).setImm(NewMB);
1716 NumRotatesCollapsed++;
1718 if (
MRI->use_nodbg_empty(SrcReg)) {
1720 "Not expecting an implicit def with this instr.");
1739 if (
MI.getOpcode() != PPC::RLDICR)
1745 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1754 if (SHMI + MEMI != 63)
1768 if (!
MRI->hasOneNonDBGUse(SrcReg))
1773 "EXTSW's second operand should be a register");
1783 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
1784 :
TII->get(PPC::EXTSWSLI_32_64),
1785 MI.getOperand(0).getReg())
1792 ++NumEXTSWAndSLDICombined;
1802 "PowerPC MI Peephole Optimization",
false,
false)
1809char 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.
This is an important base class in LLVM.
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.
@ C
The default llvm calling convention, compatible with C.
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)
Returns true if Element is found in Range.
@ 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.