51#define DEBUG_TYPE "ppc-mi-peepholes"
53STATISTIC(RemoveTOCSave,
"Number of TOC saves removed");
55 "Number of functions with multiple TOC saves that must be kept");
56STATISTIC(NumTOCSavesInPrologue,
"Number of TOC saves placed in the prologue");
57STATISTIC(NumEliminatedSExt,
"Number of eliminated sign-extensions");
58STATISTIC(NumEliminatedZExt,
"Number of eliminated zero-extensions");
59STATISTIC(NumOptADDLIs,
"Number of optimized ADD instruction fed by LI");
61 "Number of instructions converted to their immediate form");
63 "Number of functions entered in PPC MI Peepholes");
65 "Number of fixed-point iterations converting reg-reg instructions "
68 "Number of pairs of rotate left, clear left/right collapsed");
70 "Number of pairs of EXTSW and SLDI combined as EXTSWSLI");
72 "Number of LI(8) reg, 0 that are folded to r0 and removed");
76 cl::desc(
"Iterate to a fixed point when attempting to "
77 "convert reg-reg instructions to reg-imm"));
81 cl::desc(
"Convert eligible reg+reg instructions to reg+imm"));
85 cl::desc(
"enable elimination of sign-extensions"),
90 cl::desc(
"enable elimination of zero-extensions"),
95 cl::desc(
"enable optimization of conditional traps"),
99 PeepholeXToICounter,
"ppc-xtoi-peephole",
100 "Controls whether PPC reg+reg to reg+imm peephole is performed on a MI");
103 "Controls whether PPC per opcode peephole is performed on a MI");
133 bool eliminateRedundantCompare();
134 bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
138 void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
149 void addRegToUpdateWithLine(
Register Reg,
int Line);
175 "TOC pointer used in a function using PC-Relative addressing!");
178 bool Changed = simplifyCode();
181 MF.
verify(
this,
"Error in PowerPC MI Peephole optimization, compile with "
182 "-mllvm -disable-ppc-peephole");
188#define addRegToUpdate(R) addRegToUpdateWithLine(R, __LINE__)
189void PPCMIPeephole::addRegToUpdateWithLine(
Register Reg,
int Line) {
192 if (RegsToUpdate.
insert(Reg).second)
194 <<
" on line " << Line
195 <<
" for re-computation of kill flags\n");
202 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
203 MPDT = &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
204 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
205 LV = &getAnalysis<LiveVariablesWrapperPass>().getLV();
208 RegsToUpdate.
clear();
220 if (!
Reg.isVirtual())
223 return MRI->getVRegDef(Reg);
228static unsigned getKnownLeadingZeroCount(
const unsigned Reg,
232 unsigned Opcode =
MI->getOpcode();
233 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
234 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec)
235 return MI->getOperand(3).getImm();
237 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
238 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
239 return MI->getOperand(3).getImm();
241 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
242 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
243 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
244 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
245 return 32 +
MI->getOperand(3).getImm();
247 if (Opcode == PPC::ANDI_rec) {
252 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
253 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
254 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
258 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
259 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec)
263 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
264 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
265 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
266 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
269 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
270 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
271 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
272 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
275 if (Opcode == PPC::AND || Opcode == PPC::AND8 || Opcode == PPC::AND_rec ||
276 Opcode == PPC::AND8_rec)
278 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
279 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
281 if (Opcode == PPC::OR || Opcode == PPC::OR8 || Opcode == PPC::XOR ||
282 Opcode == PPC::XOR8 || Opcode == PPC::OR_rec ||
283 Opcode == PPC::OR8_rec || Opcode == PPC::XOR_rec ||
284 Opcode == PPC::XOR8_rec)
286 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
287 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
289 if (
TII->isZeroExtended(Reg,
MRI))
301void PPCMIPeephole::UpdateTOCSaves(
303 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
316 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
322 for (
auto &TOCSave : TOCSaves)
323 TOCSave.second =
false;
325 TOCSaves[
MI] =
false;
331 for (
auto &
I : TOCSaves) {
357 unsigned VisitedIndex = 0;
358 while (VisitedIndex < PHIs.
size()) {
361 PHIOp != NumOps; PHIOp += 2) {
368 unsigned Opcode =
Instr->getOpcode();
369 if (Opcode == PPC::COPY) {
371 if (!
Reg.isVirtual() ||
MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
373 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
379 if (Opcode != PPC::PHI)
394void PPCMIPeephole::convertUnprimedAccPHIs(
404 for (
unsigned PHIOp = 1, NumOps =
PHI->getNumOperands(); PHIOp != NumOps;
409 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
410 Opcode == PPC::PHI) &&
411 "Unexpected instruction");
412 if (Opcode == PPC::COPY) {
414 &PPC::ACCRCRegClass &&
415 "Unexpected register class");
417 }
else if (Opcode == PPC::IMPLICIT_DEF) {
418 Register AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
420 TII->get(PPC::IMPLICIT_DEF), AccReg);
422 PHI->getOperand(PHIOp + 1)});
423 }
else if (Opcode == PPC::PHI) {
428 "This PHI node should have already been changed.");
432 PHI->getOperand(PHIOp + 1)});
442 AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
444 *
PHI->getParent(),
PHI,
PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
445 for (
auto RegMBB : PHIOps) {
446 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
462bool PPCMIPeephole::simplifyCode() {
464 bool TrapOpt =
false;
466 std::map<MachineInstr *, bool> TOCSaves;
468 NumFunctionsEnteredInMIPeephole++;
473 bool SomethingChanged =
false;
475 NumFixedPointIterations++;
476 SomethingChanged =
false;
479 if (
MI.isDebugInstr())
486 if (!
TII->convertToImmediateForm(
MI, RRToRIRegsToUpdate))
488 for (
Register R : RRToRIRegsToUpdate)
499 NumConvertedToImmediateForm++;
500 SomethingChanged =
true;
512 auto recomputeLVForDyingInstr = [&]() {
513 if (RegsToUpdate.
empty())
516 if (!MO.isReg() || !MO.isDef() || !RegsToUpdate.
count(MO.getReg()))
519 RegsToUpdate.
erase(RegToUpdate);
523 if (!
MRI->getUniqueVRegDef(RegToUpdate))
524 MO.setReg(PPC::NoRegister);
537 recomputeLVForDyingInstr();
550 if (
MI.isDebugInstr())
557 switch (
MI.getOpcode()) {
564 if (!Src.isVirtual() || !Dst.isVirtual())
566 if (
MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
567 MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
584 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
587 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
597 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
599 Register MIDestReg =
MI.getOperand(0).getReg();
602 Folded |=
TII->onlyFoldImmediate(
UseMI,
MI, MIDestReg);
603 if (
MRI->use_nodbg_empty(MIDestReg)) {
604 ++NumLoadImmZeroFoldedAndRemoved;
622 if (
TII->isTOCSaveMI(
MI))
623 UpdateTOCSaves(TOCSaves, &
MI);
626 case PPC::XXPERMDI: {
630 int Immed =
MI.getOperand(3).getImm();
642 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
644 TRI->lookThruCopyLike(
MI.getOperand(2).getReg(),
MRI);
646 if (!(TrueReg1 == TrueReg2 && TrueReg1.
isVirtual()))
660 auto isConversionOfLoadAndSplat = [=]() ->
bool {
661 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
667 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
672 if ((Immed == 0 || Immed == 3) &&
673 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
675 "to load-and-splat/copy: ");
678 MI.getOperand(0).getReg())
679 .
add(
MI.getOperand(1));
687 if (DefOpc == PPC::XXPERMDI) {
695 if (DefReg1 != DefReg2) {
699 if (!(FeedReg1 == FeedReg2 && FeedReg1.
isVirtual()))
703 if (DefImmed == 0 || DefImmed == 3) {
708 MI.getOperand(0).getReg())
709 .
add(
MI.getOperand(1));
718 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
723 MI.getOperand(1).setReg(DefReg1);
724 MI.getOperand(2).setReg(DefReg2);
725 MI.getOperand(3).setImm(3 - Immed);
733 else if (Immed == 2 && DefImmed == 2) {
738 MI.getOperand(0).getReg())
745 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
746 DefOpc == PPC::XXPERMDIs &&
756 MI.getOperand(0).getReg())
757 .
add(
MI.getOperand(1));
766 }
else if (Immed == 2 &&
767 (DefOpc == PPC::VSPLTB || DefOpc == PPC::VSPLTH ||
768 DefOpc == PPC::VSPLTW || DefOpc == PPC::XXSPLTW ||
769 DefOpc == PPC::VSPLTISB || DefOpc == PPC::VSPLTISH ||
770 DefOpc == PPC::VSPLTISW)) {
774 LLVM_DEBUG(
dbgs() <<
"Optimizing swap(vsplt(is)?[b|h|w]|xxspltw) => "
775 "copy(vsplt(is)?[b|h|w]|xxspltw): ");
778 MI.getOperand(0).getReg())
779 .
add(
MI.getOperand(1));
781 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
782 TII->isLoadFromConstantPool(
DefMI)) {
784 if (
C &&
C->getType()->isVectorTy() &&
C->getSplatValue()) {
788 <<
"Optimizing swap(splat pattern from constant-pool) "
789 "=> copy(splat pattern from constant-pool): ");
792 MI.getOperand(0).getReg())
793 .
add(
MI.getOperand(1));
802 unsigned MyOpcode =
MI.getOpcode();
803 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
805 TRI->lookThruCopyLike(
MI.getOperand(OpNo).getReg(),
MRI);
812 auto isConvertOfSplat = [=]() ->
bool {
813 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
819 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
822 bool AlreadySplat = (MyOpcode == DefOpcode) ||
823 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
824 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
825 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
826 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
827 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
828 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
835 MI.getOperand(0).getReg())
836 .
add(
MI.getOperand(OpNo));
843 if (DefOpcode == PPC::XXSLDWI) {
849 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
850 if (ShiftOp1 == ShiftOp2) {
851 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
852 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
859 <<
" to " << NewElem <<
" in instruction: ");
863 MI.getOperand(OpNo).setReg(ShiftOp1);
864 MI.getOperand(2).setImm(NewElem);
869 case PPC::XVCVDPSP: {
872 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
895 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
896 unsigned Opc = RoundInstr->getOpcode();
897 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
898 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
900 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
901 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
903 for (
int i = 0, e =
Use.getNumOperands(); i <
e; ++i)
904 if (
Use.getOperand(i).isReg() &&
905 Use.getOperand(i).getReg() == FRSPDefines)
906 Use.getOperand(i).setReg(ConvReg1);
915 ToErase = RoundInstr;
923 removeFRSPIfPossible(P1);
924 removeFRSPIfPossible(P2);
927 removeFRSPIfPossible(P1);
933 case PPC::EXTSH8_32_64: {
935 Register NarrowReg =
MI.getOperand(1).getReg();
943 if (SrcOpcode == PPC::LHZ || SrcOpcode == PPC::LHZX) {
950 unsigned Opc = PPC::LHA;
951 bool SourceIsXForm = SrcOpcode == PPC::LHZX;
952 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSH8 ||
953 MI.getOpcode() == PPC::EXTSH8_32_64;
955 if (SourceIsXForm && MIIs64Bit)
957 else if (SourceIsXForm && !MIIs64Bit)
968 addDummyDef(
MBB, &
MI, NarrowReg);
984 case PPC::EXTSW_32_64: {
986 Register NarrowReg =
MI.getOperand(1).getReg();
994 if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) {
1002 bool IsWordAligned =
false;
1008 IsWordAligned =
true;
1012 IsWordAligned =
true;
1019 unsigned Opc = PPC::LWA_32;
1020 bool SourceIsXForm = SrcOpcode == PPC::LWZX;
1021 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSW ||
1022 MI.getOpcode() == PPC::EXTSW_32_64;
1024 if (SourceIsXForm && MIIs64Bit)
1026 else if (SourceIsXForm && !MIIs64Bit)
1031 if (!IsWordAligned && (Opc == PPC::LWA || Opc == PPC::LWA_32))
1040 addDummyDef(
MBB, &
MI, NarrowReg);
1050 NumEliminatedSExt++;
1051 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
1052 TII->isSignExtended(NarrowReg,
MRI)) {
1062 TII->promoteInstr32To64ForElimEXTSW(NarrowReg,
MRI, 0, LV);
1066 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
1070 MI.getOperand(0).getReg())
1076 NumEliminatedSExt++;
1089 if (
MI.getOperand(2).getImm() != 0)
1097 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
1104 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
1107 if (SubRegMI->
getOpcode() == PPC::COPY) {
1110 SrcMI =
MRI->getVRegDef(CopyReg);
1115 unsigned KnownZeroCount =
1117 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
1120 MI.getOperand(0).getReg())
1125 NumEliminatedZExt++;
1137 assert(PhiOp &&
"Invalid Operand!");
1140 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
1146 assert(PhiOp &&
"Invalid Operand!");
1147 assert(DominatorOp &&
"Invalid Operand!");
1168 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
1170 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
1177 ? &PPC::G8RC_and_G8RC_NOX0RegClass
1178 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1179 MRI->setRegClass(DominatorReg, TRC);
1211 MI.getOperand(0).getReg())
1221 Simplified |= emitRLDICWhenLoweringJumpTables(
MI, ToErase) ||
1222 combineSEXTAndSHL(
MI, ToErase);
1226 case PPC::ANDI8_rec:
1227 case PPC::ANDIS_rec:
1228 case PPC::ANDIS8_rec: {
1230 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
1231 if (!TrueReg.
isVirtual() || !
MRI->hasOneNonDBGUse(TrueReg))
1238 unsigned SrcOpCode = SrcMI->
getOpcode();
1239 if (SrcOpCode != PPC::RLDICL && SrcOpCode != PPC::RLDICR)
1244 DstReg =
MI.getOperand(1).getReg();
1251 if (
MI.getOpcode() == PPC::ANDIS_rec ||
1252 MI.getOpcode() == PPC::ANDIS8_rec)
1254 uint64_t LZeroAndImm = llvm::countl_zero<uint64_t>(AndImm);
1255 uint64_t RZeroAndImm = llvm::countr_zero<uint64_t>(AndImm);
1260 bool PatternResultZero =
1261 (SrcOpCode == PPC::RLDICL && (RZeroAndImm + ImmSrc > 63)) ||
1262 (SrcOpCode == PPC::RLDICR && LZeroAndImm > ImmSrc);
1266 bool PatternRemoveRotate =
1268 ((SrcOpCode == PPC::RLDICL && LZeroAndImm >= ImmSrc) ||
1269 (SrcOpCode == PPC::RLDICR && (RZeroAndImm + ImmSrc > 63)));
1271 if (!PatternResultZero && !PatternRemoveRotate)
1277 if (PatternResultZero)
1278 MI.getOperand(2).setImm(0);
1288 case PPC::RLWINM_rec:
1290 case PPC::RLWINM8_rec: {
1293 Register OrigOp1Reg =
MI.getOperand(1).isReg()
1294 ?
MI.getOperand(1).getReg()
1299 if (
MI.getOperand(1).isReg())
1305 ++NumRotatesCollapsed;
1318 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1321 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1324 if (!IsOperand2Immediate &&
1325 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1329 auto ImmOperand0 =
MI.getOperand(0).getImm();
1331 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1336 if ((ImmOperand0 == 31) ||
1337 ((ImmOperand0 & 0x10) &&
1338 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1339 ((ImmOperand0 & 0x8) &&
1340 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1341 ((ImmOperand0 & 0x2) &&
1343 ((ImmOperand0 & 0x1) &&
1345 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1360 recomputeLVForDyingInstr();
1370 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1373 NumTOCSavesInPrologue++;
1381 for (
Register Reg : RegsToUpdate) {
1382 if (!
MRI->reg_empty(Reg))
1395static bool isSupportedCmpOp(
unsigned opCode) {
1396 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1397 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1398 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1399 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1402static bool is64bitCmpOp(
unsigned opCode) {
1403 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1404 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1407static bool isSignedCmpOp(
unsigned opCode) {
1408 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1409 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1412static unsigned getSignedCmpOpCode(
unsigned opCode) {
1413 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1414 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1415 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1416 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1424 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1425 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1443 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1444 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1459static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1461 for (
unsigned I = 2, E =
Phi->getNumOperands() + 1;
I != E;
I += 2) {
1464 return Phi->getOperand(
I-1).getReg();
1475 unsigned SrcReg =
Reg;
1477 unsigned NextReg = SrcReg;
1480 NextReg = getIncomingRegForBlock(Inst, BB1);
1499 auto BII = BB.getFirstInstrTerminator();
1503 if (BB.succ_size() == 2 &&
1504 BII != BB.instr_end() &&
1505 (*BII).getOpcode() == PPC::BCC &&
1506 (*BII).getOperand(1).isReg()) {
1508 Register CndReg = (*BII).getOperand(1).getReg();
1509 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1514 if (
CMPI->getParent() != &BB)
1532 return BB.succ_size() == 1;
1535 if (!isEligibleBB(
MBB))
1539 if (NumPredBBs == 1) {
1541 if (isEligibleBB(*TmpMBB)) {
1543 MBBtoMoveCmp =
nullptr;
1547 else if (NumPredBBs == 2) {
1555 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1560 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1566 if (Pred1MBB == &
MBB)
1574 for (
int I = 1;
I <= 2;
I++)
1575 if (
CMPI->getOperand(
I).isReg()) {
1582 MBBtoMoveCmp = Pred2MBB;
1593bool PPCMIPeephole::eliminateRedundantTOCSaves(
1594 std::map<MachineInstr *, bool> &TOCSaves) {
1597 for (
auto TOCSave : TOCSaves) {
1598 if (!TOCSave.second) {
1599 TOCSave.first->eraseFromParent();
1635bool PPCMIPeephole::eliminateRedundantCompare() {
1668 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1676 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1680 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1681 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1685 unsigned NewOpCode = 0;
1686 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1688 bool SwapOperands =
false;
1700 if (!
I->getOperand(2).isImm())
1702 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1706 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1709 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1719 nullptr,
nullptr,
MRI);
1721 nullptr,
nullptr,
MRI);
1727 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1730 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1737 SwapOperands =
true;
1745 nullptr,
nullptr,
MRI);
1748 if (Cmp1Operand1 != Cmp2Operand1)
1756 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1757 int Diff = Imm1 - Imm2;
1758 if (Diff < -2 || Diff > 2)
1761 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1762 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1763 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1764 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1766 if (PredToInc2 && PredToDec1) {
1767 NewPredicate2 = PredToInc2;
1768 NewPredicate1 = PredToDec1;
1773 else if (Diff == 1) {
1776 NewPredicate2 = PredToInc2;
1778 else if (PredToDec1) {
1780 NewPredicate1 = PredToDec1;
1783 else if (Diff == -1) {
1786 NewPredicate2 = PredToDec2;
1788 else if (PredToInc1) {
1790 NewPredicate1 = PredToInc1;
1793 else if (Diff == -2) {
1794 if (PredToDec2 && PredToInc1) {
1795 NewPredicate2 = PredToDec2;
1796 NewPredicate1 = PredToInc1;
1808 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1821 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1824 if (NewPredicate1) {
1827 if (NewPredicate2) {
1834 if (IsPartiallyRedundant) {
1846 for (
int I = 1;
I <= 2;
I++) {
1853 "We cannot support if an operand comes from this BB.");
1854 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1863 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1865 TII->get(PPC::PHI), NewVReg)
1888 if (IsPartiallyRedundant) {
1891 <<
" to handle partial redundancy.\n");
1903bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI,
1905 if (
MI.getOpcode() != PPC::RLDICR)
1930 if (NewMB > 63 || NewSH > 63)
1939 if ((63 - NewSH) != MEMI)
1946 MI.setDesc(
TII->get(PPC::RLDIC));
1948 MI.getOperand(2).setImm(NewSH);
1949 MI.getOperand(3).setImm(NewMB);
1955 NumRotatesCollapsed++;
1957 if (
MRI->use_nodbg_empty(SrcReg)) {
1959 "Not expecting an implicit def with this instr.");
1978 if (
MI.getOpcode() != PPC::RLDICR)
1984 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1993 if (SHMI + MEMI != 63)
2007 if (!
MRI->hasOneNonDBGUse(SrcReg))
2012 "EXTSW's second operand should be a register");
2022 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
2023 :
TII->get(PPC::EXTSWSLI_32_64),
2024 MI.getOperand(0).getReg())
2031 ++NumEXTSWAndSLDICombined;
2044 "PowerPC MI Peephole Optimization",
false,
false)
2052char 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)
static Register UseReg(const MachineOperand &MO)
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.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
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.
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
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
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...
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *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.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, raw_ostream *OS=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger 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.
iterator_range< mop_iterator > explicit_uses()
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...
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.
@ C
The default llvm calling convention, compatible with C.
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)
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.