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<MachineDominatorTreeWrapperPass>().getDomTree();
204 MPDT = &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
205 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
206 LV = &getAnalysis<LiveVariablesWrapperPass>().getLV();
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);
463bool PPCMIPeephole::simplifyCode() {
465 bool TrapOpt =
false;
467 std::map<MachineInstr *, bool> TOCSaves;
469 NumFunctionsEnteredInMIPeephole++;
474 bool SomethingChanged =
false;
476 NumFixedPointIterations++;
477 SomethingChanged =
false;
480 if (
MI.isDebugInstr())
487 if (!
TII->convertToImmediateForm(
MI, RRToRIRegsToUpdate))
489 for (
Register R : RRToRIRegsToUpdate)
500 NumConvertedToImmediateForm++;
501 SomethingChanged =
true;
514 auto recomputeLVForDyingInstr = [&]() {
515 if (RegsToUpdate.
empty())
518 if (!MO.isReg() || !MO.isDef() || !RegsToUpdate.
count(MO.getReg()))
521 RegsToUpdate.
erase(RegToUpdate);
525 if (!
MRI->getUniqueVRegDef(RegToUpdate))
526 MO.setReg(PPC::NoRegister);
539 recomputeLVForDyingInstr();
552 if (
MI.isDebugInstr())
559 switch (
MI.getOpcode()) {
566 if (!Src.isVirtual() || !Dst.isVirtual())
568 if (
MRI->getRegClass(Src) != &PPC::UACCRCRegClass ||
569 MRI->getRegClass(Dst) != &PPC::ACCRCRegClass)
586 if (!collectUnprimedAccPHIs(
MRI, RootPHI, PHIs))
589 convertUnprimedAccPHIs(
TII,
MRI, PHIs, Dst);
599 if (!
MI.getOperand(1).isImm() ||
MI.getOperand(1).getImm() != 0)
601 Register MIDestReg =
MI.getOperand(0).getReg();
604 Folded |=
TII->onlyFoldImmediate(
UseMI,
MI, MIDestReg);
605 if (
MRI->use_nodbg_empty(MIDestReg)) {
606 ++NumLoadImmZeroFoldedAndRemoved;
624 if (
TII->isTOCSaveMI(
MI))
625 UpdateTOCSaves(TOCSaves, &
MI);
628 case PPC::XXPERMDI: {
632 int Immed =
MI.getOperand(3).getImm();
644 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
646 TRI->lookThruCopyLike(
MI.getOperand(2).getReg(),
MRI);
648 if (!(TrueReg1 == TrueReg2 && TrueReg1.
isVirtual()))
662 auto isConversionOfLoadAndSplat = [=]() ->
bool {
663 if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
669 if (LoadMI && LoadMI->
getOpcode() == PPC::LXVDSX)
674 if ((Immed == 0 || Immed == 3) &&
675 (DefOpc == PPC::LXVDSX || isConversionOfLoadAndSplat())) {
677 "to load-and-splat/copy: ");
680 MI.getOperand(0).getReg())
681 .
add(
MI.getOperand(1));
689 if (DefOpc == PPC::XXPERMDI) {
697 if (DefReg1 != DefReg2) {
701 if (!(FeedReg1 == FeedReg2 && FeedReg1.
isVirtual()))
705 if (DefImmed == 0 || DefImmed == 3) {
710 MI.getOperand(0).getReg())
711 .
add(
MI.getOperand(1));
720 else if ((Immed == 0 || Immed == 3) && DefImmed == 2) {
725 MI.getOperand(1).setReg(DefReg1);
726 MI.getOperand(2).setReg(DefReg2);
727 MI.getOperand(3).setImm(3 - Immed);
735 else if (Immed == 2 && DefImmed == 2) {
740 MI.getOperand(0).getReg())
747 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
748 DefOpc == PPC::XXPERMDIs &&
758 MI.getOperand(0).getReg())
759 .
add(
MI.getOperand(1));
768 }
else if (Immed == 2 &&
769 (DefOpc == PPC::VSPLTB || DefOpc == PPC::VSPLTH ||
770 DefOpc == PPC::VSPLTW || DefOpc == PPC::XXSPLTW ||
771 DefOpc == PPC::VSPLTISB || DefOpc == PPC::VSPLTISH ||
772 DefOpc == PPC::VSPLTISW)) {
776 LLVM_DEBUG(
dbgs() <<
"Optimizing swap(vsplt(is)?[b|h|w]|xxspltw) => "
777 "copy(vsplt(is)?[b|h|w]|xxspltw): ");
780 MI.getOperand(0).getReg())
781 .
add(
MI.getOperand(1));
783 }
else if ((Immed == 0 || Immed == 3 || Immed == 2) &&
784 TII->isLoadFromConstantPool(
DefMI)) {
786 if (
C &&
C->getType()->isVectorTy() &&
C->getSplatValue()) {
790 <<
"Optimizing swap(splat pattern from constant-pool) "
791 "=> copy(splat pattern from constant-pool): ");
794 MI.getOperand(0).getReg())
795 .
add(
MI.getOperand(1));
804 unsigned MyOpcode =
MI.getOpcode();
805 unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
807 TRI->lookThruCopyLike(
MI.getOperand(OpNo).getReg(),
MRI);
814 auto isConvertOfSplat = [=]() ->
bool {
815 if (DefOpcode != PPC::XVCVSPSXWS && DefOpcode != PPC::XVCVSPUXWS)
821 return Splt && (Splt->
getOpcode() == PPC::LXVWSX ||
824 bool AlreadySplat = (MyOpcode == DefOpcode) ||
825 (MyOpcode == PPC::VSPLTB && DefOpcode == PPC::VSPLTBs) ||
826 (MyOpcode == PPC::VSPLTH && DefOpcode == PPC::VSPLTHs) ||
827 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::XXSPLTWs) ||
828 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::LXVWSX) ||
829 (MyOpcode == PPC::XXSPLTW && DefOpcode == PPC::MTVSRWS)||
830 (MyOpcode == PPC::XXSPLTW && isConvertOfSplat());
837 MI.getOperand(0).getReg())
838 .
add(
MI.getOperand(OpNo));
845 if (DefOpcode == PPC::XXSLDWI) {
851 MI.getOperand(MyOpcode == PPC::XXSPLTW ? 2 : 1).getImm();
852 if (ShiftOp1 == ShiftOp2) {
853 unsigned NewElem = (SplatImm + ShiftImm) & 0x3;
854 if (
MRI->hasOneNonDBGUse(ShiftRes)) {
861 <<
" to " << NewElem <<
" in instruction: ");
865 MI.getOperand(OpNo).setReg(ShiftOp1);
866 MI.getOperand(2).setImm(NewElem);
871 case PPC::XVCVDPSP: {
874 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
897 auto removeFRSPIfPossible = [&](
MachineInstr *RoundInstr) {
898 unsigned Opc = RoundInstr->getOpcode();
899 if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) &&
900 MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) {
902 Register ConvReg1 = RoundInstr->getOperand(1).getReg();
903 Register FRSPDefines = RoundInstr->getOperand(0).getReg();
905 for (
int i = 0, e =
Use.getNumOperands(); i <
e; ++i)
906 if (
Use.getOperand(i).isReg() &&
907 Use.getOperand(i).getReg() == FRSPDefines)
908 Use.getOperand(i).setReg(ConvReg1);
917 ToErase = RoundInstr;
925 removeFRSPIfPossible(P1);
926 removeFRSPIfPossible(P2);
929 removeFRSPIfPossible(P1);
935 case PPC::EXTSH8_32_64: {
937 Register NarrowReg =
MI.getOperand(1).getReg();
945 if (SrcOpcode == PPC::LHZ || SrcOpcode == PPC::LHZX) {
952 unsigned Opc = PPC::LHA;
953 bool SourceIsXForm = SrcOpcode == PPC::LHZX;
954 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSH8 ||
955 MI.getOpcode() == PPC::EXTSH8_32_64;
957 if (SourceIsXForm && MIIs64Bit)
959 else if (SourceIsXForm && !MIIs64Bit)
970 addDummyDef(
MBB, &
MI, NarrowReg);
986 case PPC::EXTSW_32_64: {
988 Register NarrowReg =
MI.getOperand(1).getReg();
996 if (SrcOpcode == PPC::LWZ || SrcOpcode == PPC::LWZX) {
1004 bool IsWordAligned =
false;
1010 IsWordAligned =
true;
1014 IsWordAligned =
true;
1021 unsigned Opc = PPC::LWA_32;
1022 bool SourceIsXForm = SrcOpcode == PPC::LWZX;
1023 bool MIIs64Bit =
MI.getOpcode() == PPC::EXTSW ||
1024 MI.getOpcode() == PPC::EXTSW_32_64;
1026 if (SourceIsXForm && MIIs64Bit)
1028 else if (SourceIsXForm && !MIIs64Bit)
1033 if (!IsWordAligned && (Opc == PPC::LWA || Opc == PPC::LWA_32))
1042 addDummyDef(
MBB, &
MI, NarrowReg);
1052 NumEliminatedSExt++;
1053 }
else if (
MI.getOpcode() == PPC::EXTSW_32_64 &&
1054 TII->isSignExtended(NarrowReg,
MRI)) {
1059 MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass);
1063 MI.getOperand(0).getReg())
1069 NumEliminatedSExt++;
1082 if (
MI.getOperand(2).getImm() != 0)
1090 if (!(SrcMI && SrcMI->
getOpcode() == PPC::INSERT_SUBREG &&
1097 if (ImpDefMI->
getOpcode() != PPC::IMPLICIT_DEF)
break;
1100 if (SubRegMI->
getOpcode() == PPC::COPY) {
1103 SrcMI =
MRI->getVRegDef(CopyReg);
1108 unsigned KnownZeroCount =
1110 if (
MI.getOperand(3).getImm() <= KnownZeroCount) {
1113 MI.getOperand(0).getReg())
1118 NumEliminatedZExt++;
1130 assert(PhiOp &&
"Invalid Operand!");
1133 return DefPhiMI && (DefPhiMI->
getOpcode() == PPC::PHI) &&
1139 assert(PhiOp &&
"Invalid Operand!");
1140 assert(DominatorOp &&
"Invalid Operand!");
1161 if (isSingleUsePHI(&Op2) && dominatesAllSingleUseLIs(&Op1, &Op2))
1163 else if (!isSingleUsePHI(&Op1) || !dominatesAllSingleUseLIs(&Op2, &Op1))
1170 ? &PPC::G8RC_and_G8RC_NOX0RegClass
1171 : &PPC::GPRC_and_GPRC_NOR0RegClass;
1172 MRI->setRegClass(DominatorReg, TRC);
1204 MI.getOperand(0).getReg())
1214 Simplified |= emitRLDICWhenLoweringJumpTables(
MI, ToErase) ||
1215 combineSEXTAndSHL(
MI, ToErase);
1219 case PPC::ANDI8_rec:
1220 case PPC::ANDIS_rec:
1221 case PPC::ANDIS8_rec: {
1223 TRI->lookThruCopyLike(
MI.getOperand(1).getReg(),
MRI);
1224 if (!TrueReg.
isVirtual() || !
MRI->hasOneNonDBGUse(TrueReg))
1231 unsigned SrcOpCode = SrcMI->
getOpcode();
1232 if (SrcOpCode != PPC::RLDICL && SrcOpCode != PPC::RLDICR)
1237 DstReg =
MI.getOperand(1).getReg();
1244 if (
MI.getOpcode() == PPC::ANDIS_rec ||
1245 MI.getOpcode() == PPC::ANDIS8_rec)
1247 uint64_t LZeroAndImm = llvm::countl_zero<uint64_t>(AndImm);
1248 uint64_t RZeroAndImm = llvm::countr_zero<uint64_t>(AndImm);
1253 bool PatternResultZero =
1254 (SrcOpCode == PPC::RLDICL && (RZeroAndImm + ImmSrc > 63)) ||
1255 (SrcOpCode == PPC::RLDICR && LZeroAndImm > ImmSrc);
1259 bool PatternRemoveRotate =
1261 ((SrcOpCode == PPC::RLDICL && LZeroAndImm >= ImmSrc) ||
1262 (SrcOpCode == PPC::RLDICR && (RZeroAndImm + ImmSrc > 63)));
1264 if (!PatternResultZero && !PatternRemoveRotate)
1270 if (PatternResultZero)
1271 MI.getOperand(2).setImm(0);
1281 case PPC::RLWINM_rec:
1283 case PPC::RLWINM8_rec: {
1286 Register OrigOp1Reg =
MI.getOperand(1).isReg()
1287 ?
MI.getOperand(1).getReg()
1292 if (
MI.getOperand(1).isReg())
1298 ++NumRotatesCollapsed;
1311 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1314 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1317 if (!IsOperand2Immediate &&
1318 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1322 auto ImmOperand0 =
MI.getOperand(0).getImm();
1324 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1329 if ((ImmOperand0 == 31) ||
1330 ((ImmOperand0 & 0x10) &&
1331 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1332 ((ImmOperand0 & 0x8) &&
1333 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1334 ((ImmOperand0 & 0x2) &&
1336 ((ImmOperand0 & 0x1) &&
1338 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1353 recomputeLVForDyingInstr();
1363 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1366 NumTOCSavesInPrologue++;
1374 for (
Register Reg : RegsToUpdate) {
1375 if (!
MRI->reg_empty(Reg))
1388static bool isSupportedCmpOp(
unsigned opCode) {
1389 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1390 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1391 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1392 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1395static bool is64bitCmpOp(
unsigned opCode) {
1396 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1397 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1400static bool isSignedCmpOp(
unsigned opCode) {
1401 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1402 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1405static unsigned getSignedCmpOpCode(
unsigned opCode) {
1406 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1407 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1408 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1409 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1417 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1418 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1436 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1437 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1452static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1454 for (
unsigned I = 2, E =
Phi->getNumOperands() + 1;
I != E;
I += 2) {
1457 return Phi->getOperand(
I-1).getReg();
1468 unsigned SrcReg =
Reg;
1470 unsigned NextReg = SrcReg;
1473 NextReg = getIncomingRegForBlock(Inst, BB1);
1492 auto BII = BB.getFirstInstrTerminator();
1496 if (BB.succ_size() == 2 &&
1497 BII != BB.instr_end() &&
1498 (*BII).getOpcode() == PPC::BCC &&
1499 (*BII).getOperand(1).isReg()) {
1501 Register CndReg = (*BII).getOperand(1).getReg();
1502 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1507 if (
CMPI->getParent() != &BB)
1525 return BB.succ_size() == 1;
1528 if (!isEligibleBB(
MBB))
1532 if (NumPredBBs == 1) {
1534 if (isEligibleBB(*TmpMBB)) {
1536 MBBtoMoveCmp =
nullptr;
1540 else if (NumPredBBs == 2) {
1548 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1553 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1559 if (Pred1MBB == &
MBB)
1567 for (
int I = 1;
I <= 2;
I++)
1568 if (
CMPI->getOperand(
I).isReg()) {
1575 MBBtoMoveCmp = Pred2MBB;
1586bool PPCMIPeephole::eliminateRedundantTOCSaves(
1587 std::map<MachineInstr *, bool> &TOCSaves) {
1590 for (
auto TOCSave : TOCSaves) {
1591 if (!TOCSave.second) {
1592 TOCSave.first->eraseFromParent();
1628bool PPCMIPeephole::eliminateRedundantCompare() {
1661 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1669 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1673 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1674 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1678 unsigned NewOpCode = 0;
1679 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1681 bool SwapOperands =
false;
1693 if (!
I->getOperand(2).isImm())
1695 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1699 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1702 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1712 nullptr,
nullptr,
MRI);
1714 nullptr,
nullptr,
MRI);
1720 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1723 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1730 SwapOperands =
true;
1738 nullptr,
nullptr,
MRI);
1741 if (Cmp1Operand1 != Cmp2Operand1)
1749 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1750 int Diff = Imm1 - Imm2;
1751 if (Diff < -2 || Diff > 2)
1754 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1755 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1756 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1757 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1759 if (PredToInc2 && PredToDec1) {
1760 NewPredicate2 = PredToInc2;
1761 NewPredicate1 = PredToDec1;
1766 else if (Diff == 1) {
1769 NewPredicate2 = PredToInc2;
1771 else if (PredToDec1) {
1773 NewPredicate1 = PredToDec1;
1776 else if (Diff == -1) {
1779 NewPredicate2 = PredToDec2;
1781 else if (PredToInc1) {
1783 NewPredicate1 = PredToInc1;
1786 else if (Diff == -2) {
1787 if (PredToDec2 && PredToInc1) {
1788 NewPredicate2 = PredToDec2;
1789 NewPredicate1 = PredToInc1;
1801 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1814 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1817 if (NewPredicate1) {
1820 if (NewPredicate2) {
1827 if (IsPartiallyRedundant) {
1839 for (
int I = 1;
I <= 2;
I++) {
1846 "We cannot support if an operand comes from this BB.");
1847 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1856 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1858 TII->get(PPC::PHI), NewVReg)
1881 if (IsPartiallyRedundant) {
1884 <<
" to handle partial redundancy.\n");
1896bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI,
1898 if (
MI.getOpcode() != PPC::RLDICR)
1923 if (NewMB > 63 || NewSH > 63)
1932 if ((63 - NewSH) != MEMI)
1939 MI.setDesc(
TII->get(PPC::RLDIC));
1941 MI.getOperand(2).setImm(NewSH);
1942 MI.getOperand(3).setImm(NewMB);
1948 NumRotatesCollapsed++;
1950 if (
MRI->use_nodbg_empty(SrcReg)) {
1952 "Not expecting an implicit def with this instr.");
1971 if (
MI.getOpcode() != PPC::RLDICR)
1977 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1986 if (SHMI + MEMI != 63)
2000 if (!
MRI->hasOneNonDBGUse(SrcReg))
2005 "EXTSW's second operand should be a register");
2015 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
2016 :
TII->get(PPC::EXTSWSLI_32_64),
2017 MI.getOperand(0).getReg())
2024 ++NumEXTSWAndSLDICombined;
2037 "PowerPC MI Peephole Optimization",
false,
false)
2045char 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 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.
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.
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.