52#define DEBUG_TYPE "ppc-mi-peepholes"
54STATISTIC(RemoveTOCSave,
"Number of TOC saves removed");
56 "Number of functions with multiple TOC saves that must be kept");
57STATISTIC(NumTOCSavesInPrologue,
"Number of TOC saves placed in the prologue");
58STATISTIC(NumEliminatedSExt,
"Number of eliminated sign-extensions");
59STATISTIC(NumEliminatedZExt,
"Number of eliminated zero-extensions");
60STATISTIC(NumOptADDLIs,
"Number of optimized ADD instruction fed by LI");
62 "Number of instructions converted to their immediate form");
64 "Number of functions entered in PPC MI Peepholes");
66 "Number of fixed-point iterations converting reg-reg instructions "
69 "Number of pairs of rotate left, clear left/right collapsed");
71 "Number of pairs of EXTSW and SLDI combined as EXTSWSLI");
73 "Number of LI(8) reg, 0 that are folded to r0 and removed");
77 cl::desc(
"Iterate to a fixed point when attempting to "
78 "convert reg-reg instructions to reg-imm"));
82 cl::desc(
"Convert eligible reg+reg instructions to reg+imm"));
86 cl::desc(
"enable elimination of sign-extensions"),
91 cl::desc(
"enable elimination of zero-extensions"),
96 cl::desc(
"enable optimization of conditional traps"),
100 PeepholeXToICounter,
"ppc-xtoi-peephole",
101 "Controls whether PPC reg+reg to reg+imm peephole is performed on a MI");
104 "Controls whether PPC per opcode peephole is performed on a MI");
134 bool eliminateRedundantCompare();
135 bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
139 void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
150 void addRegToUpdateWithLine(
Register Reg,
int Line);
176 "TOC pointer used in a function using PC-Relative addressing!");
179 bool Changed = simplifyCode();
182 MF.
verify(
this,
"Error in PowerPC MI Peephole optimization, compile with "
183 "-mllvm -disable-ppc-peephole");
189#define addRegToUpdate(R) addRegToUpdateWithLine(R, __LINE__)
190void PPCMIPeephole::addRegToUpdateWithLine(
Register Reg,
int Line) {
193 if (RegsToUpdate.
insert(Reg).second)
195 <<
" on line " << Line
196 <<
" for re-computation of kill flags\n");
203 MDT = &getAnalysis<MachineDominatorTree>();
204 MPDT = &getAnalysis<MachinePostDominatorTree>();
205 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
206 LV = &getAnalysis<LiveVariables>();
209 RegsToUpdate.
clear();
221 if (!
Reg.isVirtual())
224 return MRI->getVRegDef(Reg);
229static unsigned getKnownLeadingZeroCount(
const unsigned Reg,
233 unsigned Opcode =
MI->getOpcode();
234 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
235 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec)
236 return MI->getOperand(3).getImm();
238 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
239 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
240 return MI->getOperand(3).getImm();
242 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
243 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
244 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
245 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
246 return 32 +
MI->getOperand(3).getImm();
248 if (Opcode == PPC::ANDI_rec) {
253 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
254 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
255 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
259 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
260 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec)
264 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
265 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
266 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
267 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
270 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
271 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
272 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
273 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
276 if (Opcode == PPC::AND || Opcode == PPC::AND8 || Opcode == PPC::AND_rec ||
277 Opcode == PPC::AND8_rec)
279 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
280 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
282 if (Opcode == PPC::OR || Opcode == PPC::OR8 || Opcode == PPC::XOR ||
283 Opcode == PPC::XOR8 || Opcode == PPC::OR_rec ||
284 Opcode == PPC::OR8_rec || Opcode == PPC::XOR_rec ||
285 Opcode == PPC::XOR8_rec)
287 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
288 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
290 if (
TII->isZeroExtended(Reg,
MRI))
302void PPCMIPeephole::UpdateTOCSaves(
304 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
317 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
323 for (
auto &TOCSave : TOCSaves)
324 TOCSave.second =
false;
326 TOCSaves[
MI] =
false;
332 for (
auto &
I : TOCSaves) {
358 unsigned VisitedIndex = 0;
359 while (VisitedIndex < PHIs.
size()) {
362 PHIOp != NumOps; PHIOp += 2) {
369 unsigned Opcode =
Instr->getOpcode();
370 if (Opcode == PPC::COPY) {
372 if (!
Reg.isVirtual() ||
MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
374 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
380 if (Opcode != PPC::PHI)
395void PPCMIPeephole::convertUnprimedAccPHIs(
405 for (
unsigned PHIOp = 1, NumOps =
PHI->getNumOperands(); PHIOp != NumOps;
410 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
411 Opcode == PPC::PHI) &&
412 "Unexpected instruction");
413 if (Opcode == PPC::COPY) {
415 &PPC::ACCRCRegClass &&
416 "Unexpected register class");
418 }
else if (Opcode == PPC::IMPLICIT_DEF) {
419 Register AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
421 TII->get(PPC::IMPLICIT_DEF), AccReg);
423 PHI->getOperand(PHIOp + 1)});
424 }
else if (Opcode == PPC::PHI) {
429 "This PHI node should have already been changed.");
433 PHI->getOperand(PHIOp + 1)});
443 AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
445 *
PHI->getParent(),
PHI,
PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
446 for (
auto RegMBB : PHIOps) {
447 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
460bool PPCMIPeephole::simplifyCode() {
462 bool TrapOpt =
false;
464 std::map<MachineInstr *, bool> TOCSaves;
466 NumFunctionsEnteredInMIPeephole++;
471 bool SomethingChanged =
false;
473 NumFixedPointIterations++;
474 SomethingChanged =
false;
477 if (
MI.isDebugInstr())
484 if (!
TII->convertToImmediateForm(
MI, RRToRIRegsToUpdate))
486 for (
Register R : RRToRIRegsToUpdate)
497 NumConvertedToImmediateForm++;
498 SomethingChanged =
true;
511 auto recomputeLVForDyingInstr = [&]() {
512 if (RegsToUpdate.
empty())
515 if (!MO.isReg() || !MO.isDef() || !RegsToUpdate.
count(MO.getReg()))
518 RegsToUpdate.
erase(RegToUpdate);
522 if (!
MRI->getUniqueVRegDef(RegToUpdate))
523 MO.setReg(PPC::NoRegister);
536 recomputeLVForDyingInstr();
549 if (
MI.isDebugInstr())
556 switch (
MI.getOpcode()) {
563 if (!Src.isVirtual() || !Dst.isVirtual())
565 if (
MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
566 MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
583 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
586 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
596 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
598 Register MIDestReg =
MI.getOperand(0).getReg();
601 Folded |=
TII->onlyFoldImmediate(
UseMI,
MI, MIDestReg);
602 if (
MRI->use_nodbg_empty(MIDestReg)) {
603 ++NumLoadImmZeroFoldedAndRemoved;
621 if (
TII->isTOCSaveMI(
MI))
622 UpdateTOCSaves(TOCSaves, &
MI);
625 case PPC::XXPERMDI: {
629 int Immed =
MI.getOperand(3).getImm();
641 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
643 TRI->lookThruCopyLike(
MI.getOperand(2).getReg(),
MRI);
645 if (!(TrueReg1 == TrueReg2 && TrueReg1.
isVirtual()))
659 auto isConversionOfLoadAndSplat = [=]() ->
bool {
660 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
666 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
671 if ((Immed == 0 || Immed == 3) &&
672 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
674 "to load-and-splat/copy: ");
677 MI.getOperand(0).getReg())
678 .
add(
MI.getOperand(1));
686 if (DefOpc == PPC::XXPERMDI) {
694 if (DefReg1 != DefReg2) {
698 if (!(FeedReg1 == FeedReg2 && FeedReg1.
isVirtual()))
702 if (DefImmed == 0 || DefImmed == 3) {
707 MI.getOperand(0).getReg())
708 .
add(
MI.getOperand(1));
717 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
722 MI.getOperand(1).setReg(DefReg1);
723 MI.getOperand(2).setReg(DefReg2);
724 MI.getOperand(3).setImm(3 - Immed);
732 else if (Immed == 2 && DefImmed == 2) {
737 MI.getOperand(0).getReg())
744 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
745 DefOpc == PPC::XXPERMDIs &&
755 MI.getOperand(0).getReg())
756 .
add(
MI.getOperand(1));
765 }
else if (Immed == 2 &&
766 (DefOpc == PPC::VSPLTB || DefOpc == PPC::VSPLTH ||
767 DefOpc == PPC::VSPLTW || DefOpc == PPC::XXSPLTW ||
768 DefOpc == PPC::VSPLTISB || DefOpc == PPC::VSPLTISH ||
769 DefOpc == PPC::VSPLTISW)) {
773 LLVM_DEBUG(
dbgs() <<
"Optimizing swap(vsplt(is)?[b|h|w]|xxspltw) => "
774 "copy(vsplt(is)?[b|h|w]|xxspltw): ");
777 MI.getOperand(0).getReg())
778 .
add(
MI.getOperand(1));
780 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
781 TII->isLoadFromConstantPool(
DefMI)) {
783 if (
C &&
C->getType()->isVectorTy() &&
C->getSplatValue()) {
787 <<
"Optimizing swap(splat pattern from constant-pool) "
788 "=> copy(splat pattern from constant-pool): ");
791 MI.getOperand(0).getReg())
792 .
add(
MI.getOperand(1));
801 unsigned MyOpcode =
MI.getOpcode();
802 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
804 TRI->lookThruCopyLike(
MI.getOperand(OpNo).getReg(),
MRI);
811 auto isConvertOfSplat = [=]() ->
bool {
812 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
818 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
821 bool AlreadySplat = (MyOpcode == DefOpcode) ||
822 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
823 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
824 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
825 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
826 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
827 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
834 MI.getOperand(0).getReg())
835 .
add(
MI.getOperand(OpNo));
842 if (DefOpcode == PPC::XXSLDWI) {
848 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
849 if (ShiftOp1 == ShiftOp2) {
850 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
851 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
858 <<
" to " << NewElem <<
" in instruction: ");
862 MI.getOperand(OpNo).setReg(ShiftOp1);
863 MI.getOperand(2).setImm(NewElem);
868 case PPC::XVCVDPSP: {
871 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
894 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
895 unsigned Opc = RoundInstr->getOpcode();
896 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
897 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
899 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
900 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
902 for (
int i = 0, e =
Use.getNumOperands(); i <
e; ++i)
903 if (
Use.getOperand(i).isReg() &&
904 Use.getOperand(i).getReg() == FRSPDefines)
905 Use.getOperand(i).setReg(ConvReg1);
914 ToErase = RoundInstr;
922 removeFRSPIfPossible(P1);
923 removeFRSPIfPossible(P2);
926 removeFRSPIfPossible(P1);
932 case PPC::EXTSH8_32_64: {
934 Register NarrowReg =
MI.getOperand(1).getReg();
942 if (SrcOpcode == PPC::LHZ || SrcOpcode == PPC::LHZX) {
949 unsigned Opc = PPC::LHA;
950 bool SourceIsXForm = SrcOpcode == PPC::LHZX;
951 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSH8 ||
952 MI.getOpcode() == PPC::EXTSH8_32_64;
954 if (SourceIsXForm && MIIs64Bit)
956 else if (SourceIsXForm && !MIIs64Bit)
967 addDummyDef(
MBB, &
MI, NarrowReg);
983 case PPC::EXTSW_32_64: {
985 Register NarrowReg =
MI.getOperand(1).getReg();
993 if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) {
1001 bool IsWordAligned =
false;
1007 IsWordAligned =
true;
1011 IsWordAligned =
true;
1018 unsigned Opc = PPC::LWA_32;
1019 bool SourceIsXForm = SrcOpcode == PPC::LWZX;
1020 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSW ||
1021 MI.getOpcode() == PPC::EXTSW_32_64;
1023 if (SourceIsXForm && MIIs64Bit)
1025 else if (SourceIsXForm && !MIIs64Bit)
1030 if (!IsWordAligned && (Opc == PPC::LWA || Opc == PPC::LWA_32))
1039 addDummyDef(
MBB, &
MI, NarrowReg);
1049 NumEliminatedSExt++;
1050 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
1051 TII->isSignExtended(NarrowReg,
MRI)) {
1056 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
1060 MI.getOperand(0).getReg())
1066 NumEliminatedSExt++;
1079 if (
MI.getOperand(2).getImm() != 0)
1087 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
1094 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
1097 if (SubRegMI->
getOpcode() == PPC::COPY) {
1100 SrcMI =
MRI->getVRegDef(CopyReg);
1105 unsigned KnownZeroCount =
1107 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
1110 MI.getOperand(0).getReg())
1115 NumEliminatedZExt++;
1127 assert(PhiOp &&
"Invalid Operand!");
1130 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
1136 assert(PhiOp &&
"Invalid Operand!");
1137 assert(DominatorOp &&
"Invalid Operand!");
1158 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
1160 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
1167 ? &PPC::G8RC_and_G8RC_NOX0RegClass
1168 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1169 MRI->setRegClass(DominatorReg, TRC);
1201 MI.getOperand(0).getReg())
1211 Simplified |= emitRLDICWhenLoweringJumpTables(
MI, ToErase) ||
1212 combineSEXTAndSHL(
MI, ToErase);
1216 case PPC::ANDI8_rec:
1217 case PPC::ANDIS_rec:
1218 case PPC::ANDIS8_rec: {
1220 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
1221 if (!TrueReg.
isVirtual() || !
MRI->hasOneNonDBGUse(TrueReg))
1228 unsigned SrcOpCode = SrcMI->
getOpcode();
1229 if (SrcOpCode != PPC::RLDICL && SrcOpCode != PPC::RLDICR)
1234 DstReg =
MI.getOperand(1).getReg();
1241 if (
MI.getOpcode() == PPC::ANDIS_rec ||
1242 MI.getOpcode() == PPC::ANDIS8_rec)
1244 uint64_t LZeroAndImm = llvm::countl_zero<uint64_t>(AndImm);
1245 uint64_t RZeroAndImm = llvm::countr_zero<uint64_t>(AndImm);
1250 bool PatternResultZero =
1251 (SrcOpCode == PPC::RLDICL && (RZeroAndImm + ImmSrc > 63)) ||
1252 (SrcOpCode == PPC::RLDICR && LZeroAndImm > ImmSrc);
1256 bool PatternRemoveRotate =
1258 ((SrcOpCode == PPC::RLDICL && LZeroAndImm >= ImmSrc) ||
1259 (SrcOpCode == PPC::RLDICR && (RZeroAndImm + ImmSrc > 63)));
1261 if (!PatternResultZero && !PatternRemoveRotate)
1267 if (PatternResultZero)
1268 MI.getOperand(2).setImm(0);
1278 case PPC::RLWINM_rec:
1280 case PPC::RLWINM8_rec: {
1283 Register OrigOp1Reg =
MI.getOperand(1).isReg()
1284 ?
MI.getOperand(1).getReg()
1289 if (
MI.getOperand(1).isReg())
1291 ++NumRotatesCollapsed;
1304 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1307 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1310 if (!IsOperand2Immediate &&
1311 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1315 auto ImmOperand0 =
MI.getOperand(0).getImm();
1317 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1322 if ((ImmOperand0 == 31) ||
1323 ((ImmOperand0 & 0x10) &&
1324 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1325 ((ImmOperand0 & 0x8) &&
1326 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1327 ((ImmOperand0 & 0x2) &&
1329 ((ImmOperand0 & 0x1) &&
1331 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1346 recomputeLVForDyingInstr();
1356 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1359 NumTOCSavesInPrologue++;
1367 for (
Register Reg : RegsToUpdate) {
1368 if (!
MRI->reg_empty(Reg))
1381static bool isSupportedCmpOp(
unsigned opCode) {
1382 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1383 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1384 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1385 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1388static bool is64bitCmpOp(
unsigned opCode) {
1389 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1390 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1393static bool isSignedCmpOp(
unsigned opCode) {
1394 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1395 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1398static unsigned getSignedCmpOpCode(
unsigned opCode) {
1399 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1400 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1401 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1402 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1410 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1411 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1429 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1430 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1445static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1447 for (
unsigned I = 2, E =
Phi->getNumOperands() + 1;
I != E;
I += 2) {
1450 return Phi->getOperand(
I-1).getReg();
1461 unsigned SrcReg =
Reg;
1463 unsigned NextReg = SrcReg;
1466 NextReg = getIncomingRegForBlock(Inst, BB1);
1485 auto BII = BB.getFirstInstrTerminator();
1489 if (BB.succ_size() == 2 &&
1490 BII != BB.instr_end() &&
1491 (*BII).getOpcode() == PPC::BCC &&
1492 (*BII).getOperand(1).isReg()) {
1494 Register CndReg = (*BII).getOperand(1).getReg();
1495 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1500 if (
CMPI->getParent() != &BB)
1518 return BB.succ_size() == 1;
1521 if (!isEligibleBB(
MBB))
1525 if (NumPredBBs == 1) {
1527 if (isEligibleBB(*TmpMBB)) {
1529 MBBtoMoveCmp =
nullptr;
1533 else if (NumPredBBs == 2) {
1541 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1546 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1552 if (Pred1MBB == &
MBB)
1560 for (
int I = 1;
I <= 2;
I++)
1561 if (
CMPI->getOperand(
I).isReg()) {
1568 MBBtoMoveCmp = Pred2MBB;
1579bool PPCMIPeephole::eliminateRedundantTOCSaves(
1580 std::map<MachineInstr *, bool> &TOCSaves) {
1583 for (
auto TOCSave : TOCSaves) {
1584 if (!TOCSave.second) {
1585 TOCSave.first->eraseFromParent();
1621bool PPCMIPeephole::eliminateRedundantCompare() {
1654 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1662 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1666 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1667 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1671 unsigned NewOpCode = 0;
1672 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1674 bool SwapOperands =
false;
1686 if (!
I->getOperand(2).isImm())
1688 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1692 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1695 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1705 nullptr,
nullptr,
MRI);
1707 nullptr,
nullptr,
MRI);
1713 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1716 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1723 SwapOperands =
true;
1731 nullptr,
nullptr,
MRI);
1734 if (Cmp1Operand1 != Cmp2Operand1)
1742 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1743 int Diff = Imm1 - Imm2;
1744 if (Diff < -2 || Diff > 2)
1747 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1748 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1749 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1750 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1752 if (PredToInc2 && PredToDec1) {
1753 NewPredicate2 = PredToInc2;
1754 NewPredicate1 = PredToDec1;
1759 else if (Diff == 1) {
1762 NewPredicate2 = PredToInc2;
1764 else if (PredToDec1) {
1766 NewPredicate1 = PredToDec1;
1769 else if (Diff == -1) {
1772 NewPredicate2 = PredToDec2;
1774 else if (PredToInc1) {
1776 NewPredicate1 = PredToInc1;
1779 else if (Diff == -2) {
1780 if (PredToDec2 && PredToInc1) {
1781 NewPredicate2 = PredToDec2;
1782 NewPredicate1 = PredToInc1;
1794 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1807 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1810 if (NewPredicate1) {
1813 if (NewPredicate2) {
1820 if (IsPartiallyRedundant) {
1832 for (
int I = 1;
I <= 2;
I++) {
1839 "We cannot support if an operand comes from this BB.");
1840 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1849 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1851 TII->get(PPC::PHI), NewVReg)
1874 if (IsPartiallyRedundant) {
1877 <<
" to handle partial redundancy.\n");
1889bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI,
1891 if (
MI.getOpcode() != PPC::RLDICR)
1916 if (NewMB > 63 || NewSH > 63)
1925 if ((63 - NewSH) != MEMI)
1932 MI.setDesc(
TII->get(PPC::RLDIC));
1934 MI.getOperand(2).setImm(NewSH);
1935 MI.getOperand(3).setImm(NewMB);
1941 NumRotatesCollapsed++;
1943 if (
MRI->use_nodbg_empty(SrcReg)) {
1945 "Not expecting an implicit def with this instr.");
1964 if (
MI.getOpcode() != PPC::RLDICR)
1970 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1979 if (SHMI + MEMI != 63)
1993 if (!
MRI->hasOneNonDBGUse(SrcReg))
1998 "EXTSW's second operand should be a register");
2008 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
2009 :
TII->get(PPC::EXTSWSLI_32_64),
2010 MI.getOperand(0).getReg())
2017 ++NumEXTSWAndSLDICombined;
2030 "PowerPC MI Peephole Optimization",
false,
false)
2038char PPCMIPeephole::
ID = 0;
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define addRegToUpdate(R)
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.
This class represents an Operation in the Expression.
static bool shouldExecute(unsigned CounterName)
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.
void recomputeForSingleDefVirtReg(Register Reg)
Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...
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.
BlockFrequency 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
bool verify(Pass *p=nullptr, const char *Banner=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use.
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.
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
iterator_range< mop_iterator > operands()
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
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.
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 unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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)
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
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.