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"),
126 bool eliminateRedundantCompare();
127 bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
131 void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
142 void addRegToUpdateWithLine(
Register Reg,
int Line);
168 "TOC pointer used in a function using PC-Relative addressing!");
171 bool Changed = simplifyCode();
174 MF.
verify(
this,
"Error in PowerPC MI Peephole optimization, compile with "
175 "-mllvm -disable-ppc-peephole");
181#define addRegToUpdate(R) addRegToUpdateWithLine(R, __LINE__)
182void PPCMIPeephole::addRegToUpdateWithLine(
Register Reg,
int Line) {
185 if (RegsToUpdate.
insert(Reg).second)
187 <<
" on line " << Line
188 <<
" for re-computation of kill flags\n");
195 MDT = &getAnalysis<MachineDominatorTree>();
196 MPDT = &getAnalysis<MachinePostDominatorTree>();
197 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
198 LV = &getAnalysis<LiveVariables>();
201 RegsToUpdate.
clear();
213 if (!
Reg.isVirtual())
216 return MRI->getVRegDef(Reg);
221static unsigned getKnownLeadingZeroCount(
const unsigned Reg,
225 unsigned Opcode =
MI->getOpcode();
226 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
227 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec)
228 return MI->getOperand(3).getImm();
230 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
231 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
232 return MI->getOperand(3).getImm();
234 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
235 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
236 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
237 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
238 return 32 +
MI->getOperand(3).getImm();
240 if (Opcode == PPC::ANDI_rec) {
245 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
246 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
247 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
251 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
252 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec)
256 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
257 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
258 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
259 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
262 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
263 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
264 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
265 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
268 if (Opcode == PPC::AND || Opcode == PPC::AND8 || Opcode == PPC::AND_rec ||
269 Opcode == PPC::AND8_rec)
271 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
272 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
274 if (Opcode == PPC::OR || Opcode == PPC::OR8 || Opcode == PPC::XOR ||
275 Opcode == PPC::XOR8 || Opcode == PPC::OR_rec ||
276 Opcode == PPC::OR8_rec || Opcode == PPC::XOR_rec ||
277 Opcode == PPC::XOR8_rec)
279 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
280 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
282 if (
TII->isZeroExtended(Reg,
MRI))
294void PPCMIPeephole::UpdateTOCSaves(
296 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
309 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
315 for (
auto &TOCSave : TOCSaves)
316 TOCSave.second =
false;
318 TOCSaves[
MI] =
false;
324 for (
auto &
I : TOCSaves) {
350 unsigned VisitedIndex = 0;
351 while (VisitedIndex < PHIs.
size()) {
354 PHIOp != NumOps; PHIOp += 2) {
361 unsigned Opcode =
Instr->getOpcode();
362 if (Opcode == PPC::COPY) {
364 if (!
Reg.isVirtual() ||
MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
366 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
372 if (Opcode != PPC::PHI)
387void PPCMIPeephole::convertUnprimedAccPHIs(
397 for (
unsigned PHIOp = 1, NumOps =
PHI->getNumOperands(); PHIOp != NumOps;
402 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
403 Opcode == PPC::PHI) &&
404 "Unexpected instruction");
405 if (Opcode == PPC::COPY) {
407 &PPC::ACCRCRegClass &&
408 "Unexpected register class");
410 }
else if (Opcode == PPC::IMPLICIT_DEF) {
411 Register AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
413 TII->get(PPC::IMPLICIT_DEF), AccReg);
415 PHI->getOperand(PHIOp + 1)});
416 }
else if (Opcode == PPC::PHI) {
421 "This PHI node should have already been changed.");
425 PHI->getOperand(PHIOp + 1)});
435 AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
437 *
PHI->getParent(),
PHI,
PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
438 for (
auto RegMBB : PHIOps) {
439 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
452bool PPCMIPeephole::simplifyCode() {
454 bool TrapOpt =
false;
456 std::map<MachineInstr *, bool> TOCSaves;
458 NumFunctionsEnteredInMIPeephole++;
463 bool SomethingChanged =
false;
465 NumFixedPointIterations++;
466 SomethingChanged =
false;
469 if (
MI.isDebugInstr())
473 if (!
TII->convertToImmediateForm(
MI, RRToRIRegsToUpdate))
475 for (
Register R : RRToRIRegsToUpdate)
486 NumConvertedToImmediateForm++;
487 SomethingChanged =
true;
500 auto recomputeLVForDyingInstr = [&]() {
501 if (RegsToUpdate.
empty())
504 if (!MO.isReg() || !MO.isDef() || !RegsToUpdate.
count(MO.getReg()))
507 RegsToUpdate.
erase(RegToUpdate);
511 if (!
MRI->getUniqueVRegDef(RegToUpdate))
512 MO.setReg(PPC::NoRegister);
525 recomputeLVForDyingInstr();
538 if (
MI.isDebugInstr())
542 switch (
MI.getOpcode()) {
549 if (!Src.isVirtual() || !Dst.isVirtual())
551 if (
MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
552 MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
569 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
572 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
582 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
584 Register MIDestReg =
MI.getOperand(0).getReg();
587 Folded |=
TII->onlyFoldImmediate(
UseMI,
MI, MIDestReg);
588 if (
MRI->use_nodbg_empty(MIDestReg)) {
589 ++NumLoadImmZeroFoldedAndRemoved;
607 if (
TII->isTOCSaveMI(
MI))
608 UpdateTOCSaves(TOCSaves, &
MI);
611 case PPC::XXPERMDI: {
615 int Immed =
MI.getOperand(3).getImm();
627 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
629 TRI->lookThruCopyLike(
MI.getOperand(2).getReg(),
MRI);
631 if (!(TrueReg1 == TrueReg2 && TrueReg1.
isVirtual()))
645 auto isConversionOfLoadAndSplat = [=]() ->
bool {
646 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
652 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
657 if ((Immed == 0 || Immed == 3) &&
658 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
660 "to load-and-splat/copy: ");
663 MI.getOperand(0).getReg())
664 .
add(
MI.getOperand(1));
672 if (DefOpc == PPC::XXPERMDI) {
680 if (DefReg1 != DefReg2) {
684 if (!(FeedReg1 == FeedReg2 && FeedReg1.
isVirtual()))
688 if (DefImmed == 0 || DefImmed == 3) {
693 MI.getOperand(0).getReg())
694 .
add(
MI.getOperand(1));
703 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
708 MI.getOperand(1).setReg(DefReg1);
709 MI.getOperand(2).setReg(DefReg2);
710 MI.getOperand(3).setImm(3 - Immed);
718 else if (Immed == 2 && DefImmed == 2) {
723 MI.getOperand(0).getReg())
730 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
731 DefOpc == PPC::XXPERMDIs &&
741 MI.getOperand(0).getReg())
742 .
add(
MI.getOperand(1));
751 }
else if (Immed == 2 &&
752 (DefOpc == PPC::VSPLTB || DefOpc == PPC::VSPLTH ||
753 DefOpc == PPC::VSPLTW || DefOpc == PPC::XXSPLTW ||
754 DefOpc == PPC::VSPLTISB || DefOpc == PPC::VSPLTISH ||
755 DefOpc == PPC::VSPLTISW)) {
759 LLVM_DEBUG(
dbgs() <<
"Optimizing swap(vsplt(is)?[b|h|w]|xxspltw) => "
760 "copy(vsplt(is)?[b|h|w]|xxspltw): ");
763 MI.getOperand(0).getReg())
764 .
add(
MI.getOperand(1));
766 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
767 TII->isLoadFromConstantPool(
DefMI)) {
769 if (
C &&
C->getType()->isVectorTy() &&
C->getSplatValue()) {
773 <<
"Optimizing swap(splat pattern from constant-pool) "
774 "=> copy(splat pattern from constant-pool): ");
777 MI.getOperand(0).getReg())
778 .
add(
MI.getOperand(1));
787 unsigned MyOpcode =
MI.getOpcode();
788 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
790 TRI->lookThruCopyLike(
MI.getOperand(OpNo).getReg(),
MRI);
797 auto isConvertOfSplat = [=]() ->
bool {
798 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
804 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
807 bool AlreadySplat = (MyOpcode == DefOpcode) ||
808 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
809 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
810 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
811 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
812 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
813 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
820 MI.getOperand(0).getReg())
821 .
add(
MI.getOperand(OpNo));
828 if (DefOpcode == PPC::XXSLDWI) {
834 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
835 if (ShiftOp1 == ShiftOp2) {
836 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
837 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
844 <<
" to " << NewElem <<
" in instruction: ");
848 MI.getOperand(OpNo).setReg(ShiftOp1);
849 MI.getOperand(2).setImm(NewElem);
854 case PPC::XVCVDPSP: {
857 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
880 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
881 unsigned Opc = RoundInstr->getOpcode();
882 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
883 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
885 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
886 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
888 for (
int i = 0, e =
Use.getNumOperands(); i <
e; ++i)
889 if (
Use.getOperand(i).isReg() &&
890 Use.getOperand(i).getReg() == FRSPDefines)
891 Use.getOperand(i).setReg(ConvReg1);
900 ToErase = RoundInstr;
908 removeFRSPIfPossible(P1);
909 removeFRSPIfPossible(P2);
912 removeFRSPIfPossible(P1);
918 case PPC::EXTSH8_32_64: {
920 Register NarrowReg =
MI.getOperand(1).getReg();
928 if (SrcOpcode == PPC::LHZ || SrcOpcode == PPC::LHZX) {
935 unsigned Opc = PPC::LHA;
936 bool SourceIsXForm = SrcOpcode == PPC::LHZX;
937 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSH8 ||
938 MI.getOpcode() == PPC::EXTSH8_32_64;
940 if (SourceIsXForm && MIIs64Bit)
942 else if (SourceIsXForm && !MIIs64Bit)
953 addDummyDef(
MBB, &
MI, NarrowReg);
969 case PPC::EXTSW_32_64: {
971 Register NarrowReg =
MI.getOperand(1).getReg();
979 if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) {
987 bool IsWordAligned =
false;
993 IsWordAligned =
true;
997 IsWordAligned =
true;
1004 unsigned Opc = PPC::LWA_32;
1005 bool SourceIsXForm = SrcOpcode == PPC::LWZX;
1006 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSW ||
1007 MI.getOpcode() == PPC::EXTSW_32_64;
1009 if (SourceIsXForm && MIIs64Bit)
1011 else if (SourceIsXForm && !MIIs64Bit)
1016 if (!IsWordAligned && (Opc == PPC::LWA || Opc == PPC::LWA_32))
1025 addDummyDef(
MBB, &
MI, NarrowReg);
1035 NumEliminatedSExt++;
1036 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
1037 TII->isSignExtended(NarrowReg,
MRI)) {
1042 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
1046 MI.getOperand(0).getReg())
1052 NumEliminatedSExt++;
1065 if (
MI.getOperand(2).getImm() != 0)
1073 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
1080 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
1083 if (SubRegMI->
getOpcode() == PPC::COPY) {
1086 SrcMI =
MRI->getVRegDef(CopyReg);
1091 unsigned KnownZeroCount =
1093 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
1096 MI.getOperand(0).getReg())
1101 NumEliminatedZExt++;
1113 assert(PhiOp &&
"Invalid Operand!");
1116 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
1122 assert(PhiOp &&
"Invalid Operand!");
1123 assert(DominatorOp &&
"Invalid Operand!");
1144 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
1146 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
1153 ? &PPC::G8RC_and_G8RC_NOX0RegClass
1154 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1155 MRI->setRegClass(DominatorReg, TRC);
1187 MI.getOperand(0).getReg())
1197 Simplified |= emitRLDICWhenLoweringJumpTables(
MI, ToErase) ||
1198 combineSEXTAndSHL(
MI, ToErase);
1202 case PPC::ANDI8_rec:
1203 case PPC::ANDIS_rec:
1204 case PPC::ANDIS8_rec: {
1206 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
1207 if (!TrueReg.
isVirtual() || !
MRI->hasOneNonDBGUse(TrueReg))
1214 unsigned SrcOpCode = SrcMI->
getOpcode();
1215 if (SrcOpCode != PPC::RLDICL && SrcOpCode != PPC::RLDICR)
1220 DstReg =
MI.getOperand(1).getReg();
1227 if (
MI.getOpcode() == PPC::ANDIS_rec ||
1228 MI.getOpcode() == PPC::ANDIS8_rec)
1230 uint64_t LZeroAndImm = llvm::countl_zero<uint64_t>(AndImm);
1231 uint64_t RZeroAndImm = llvm::countr_zero<uint64_t>(AndImm);
1236 bool PatternResultZero =
1237 (SrcOpCode == PPC::RLDICL && (RZeroAndImm + ImmSrc > 63)) ||
1238 (SrcOpCode == PPC::RLDICR && LZeroAndImm > ImmSrc);
1242 bool PatternRemoveRotate =
1244 ((SrcOpCode == PPC::RLDICL && LZeroAndImm >= ImmSrc) ||
1245 (SrcOpCode == PPC::RLDICR && (RZeroAndImm + ImmSrc > 63)));
1247 if (!PatternResultZero && !PatternRemoveRotate)
1253 if (PatternResultZero)
1254 MI.getOperand(2).setImm(0);
1264 case PPC::RLWINM_rec:
1266 case PPC::RLWINM8_rec: {
1269 Register OrigOp1Reg =
MI.getOperand(1).isReg()
1270 ?
MI.getOperand(1).getReg()
1275 if (
MI.getOperand(1).isReg())
1277 ++NumRotatesCollapsed;
1290 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1293 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1296 if (!IsOperand2Immediate &&
1297 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1301 auto ImmOperand0 =
MI.getOperand(0).getImm();
1303 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1308 if ((ImmOperand0 == 31) ||
1309 ((ImmOperand0 & 0x10) &&
1310 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1311 ((ImmOperand0 & 0x8) &&
1312 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1313 ((ImmOperand0 & 0x2) &&
1315 ((ImmOperand0 & 0x1) &&
1317 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1332 recomputeLVForDyingInstr();
1342 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1345 NumTOCSavesInPrologue++;
1353 for (
Register Reg : RegsToUpdate) {
1354 if (!
MRI->reg_empty(Reg))
1367static bool isSupportedCmpOp(
unsigned opCode) {
1368 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1369 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1370 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1371 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1374static bool is64bitCmpOp(
unsigned opCode) {
1375 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1376 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1379static bool isSignedCmpOp(
unsigned opCode) {
1380 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1381 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1384static unsigned getSignedCmpOpCode(
unsigned opCode) {
1385 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1386 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1387 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1388 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1396 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1397 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1415 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1416 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1431static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1433 for (
unsigned I = 2, E =
Phi->getNumOperands() + 1;
I != E;
I += 2) {
1436 return Phi->getOperand(
I-1).getReg();
1447 unsigned SrcReg =
Reg;
1449 unsigned NextReg = SrcReg;
1452 NextReg = getIncomingRegForBlock(Inst, BB1);
1471 auto BII = BB.getFirstInstrTerminator();
1475 if (BB.succ_size() == 2 &&
1476 BII != BB.instr_end() &&
1477 (*BII).getOpcode() == PPC::BCC &&
1478 (*BII).getOperand(1).isReg()) {
1480 Register CndReg = (*BII).getOperand(1).getReg();
1481 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1486 if (
CMPI->getParent() != &BB)
1504 return BB.succ_size() == 1;
1507 if (!isEligibleBB(
MBB))
1511 if (NumPredBBs == 1) {
1513 if (isEligibleBB(*TmpMBB)) {
1515 MBBtoMoveCmp =
nullptr;
1519 else if (NumPredBBs == 2) {
1527 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1532 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1538 if (Pred1MBB == &
MBB)
1546 for (
int I = 1;
I <= 2;
I++)
1547 if (
CMPI->getOperand(
I).isReg()) {
1554 MBBtoMoveCmp = Pred2MBB;
1565bool PPCMIPeephole::eliminateRedundantTOCSaves(
1566 std::map<MachineInstr *, bool> &TOCSaves) {
1569 for (
auto TOCSave : TOCSaves) {
1570 if (!TOCSave.second) {
1571 TOCSave.first->eraseFromParent();
1607bool PPCMIPeephole::eliminateRedundantCompare() {
1640 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1648 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1652 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1653 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1657 unsigned NewOpCode = 0;
1658 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1660 bool SwapOperands =
false;
1672 if (!
I->getOperand(2).isImm())
1674 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1678 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1681 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1691 nullptr,
nullptr,
MRI);
1693 nullptr,
nullptr,
MRI);
1699 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1702 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1709 SwapOperands =
true;
1717 nullptr,
nullptr,
MRI);
1720 if (Cmp1Operand1 != Cmp2Operand1)
1728 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1729 int Diff = Imm1 - Imm2;
1730 if (Diff < -2 || Diff > 2)
1733 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1734 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1735 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1736 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1738 if (PredToInc2 && PredToDec1) {
1739 NewPredicate2 = PredToInc2;
1740 NewPredicate1 = PredToDec1;
1745 else if (Diff == 1) {
1748 NewPredicate2 = PredToInc2;
1750 else if (PredToDec1) {
1752 NewPredicate1 = PredToDec1;
1755 else if (Diff == -1) {
1758 NewPredicate2 = PredToDec2;
1760 else if (PredToInc1) {
1762 NewPredicate1 = PredToInc1;
1765 else if (Diff == -2) {
1766 if (PredToDec2 && PredToInc1) {
1767 NewPredicate2 = PredToDec2;
1768 NewPredicate1 = PredToInc1;
1780 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1793 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1796 if (NewPredicate1) {
1799 if (NewPredicate2) {
1806 if (IsPartiallyRedundant) {
1818 for (
int I = 1;
I <= 2;
I++) {
1825 "We cannot support if an operand comes from this BB.");
1826 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1835 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1837 TII->get(PPC::PHI), NewVReg)
1860 if (IsPartiallyRedundant) {
1863 <<
" to handle partial redundancy.\n");
1875bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI,
1877 if (
MI.getOpcode() != PPC::RLDICR)
1902 if (NewMB > 63 || NewSH > 63)
1911 if ((63 - NewSH) != MEMI)
1918 MI.setDesc(
TII->get(PPC::RLDIC));
1920 MI.getOperand(2).setImm(NewSH);
1921 MI.getOperand(3).setImm(NewMB);
1927 NumRotatesCollapsed++;
1929 if (
MRI->use_nodbg_empty(SrcReg)) {
1931 "Not expecting an implicit def with this instr.");
1950 if (
MI.getOpcode() != PPC::RLDICR)
1956 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1965 if (SHMI + MEMI != 63)
1979 if (!
MRI->hasOneNonDBGUse(SrcReg))
1984 "EXTSW's second operand should be a register");
1994 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
1995 :
TII->get(PPC::EXTSWSLI_32_64),
1996 MI.getOperand(0).getReg())
2003 ++NumEXTSWAndSLDICombined;
2016 "PowerPC MI Peephole Optimization",
false,
false)
2024char PPCMIPeephole::
ID = 0;
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
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.