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<MachineBlockFrequencyInfo>();
206 LV = &getAnalysis<LiveVariables>();
209 RegsToUpdate.
clear();
221 if (!
Reg.isVirtual())
224 return MRI->getVRegDef(Reg);
229static unsigned getKnownLeadingZeroCount(
const unsigned Reg,
233 unsigned Opcode =
MI->getOpcode();
234 if (Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
235 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec)
236 return MI->getOperand(3).getImm();
238 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
239 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
240 return MI->getOperand(3).getImm();
242 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
243 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
244 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
245 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
246 return 32 +
MI->getOperand(3).getImm();
248 if (Opcode == PPC::ANDI_rec) {
253 if (Opcode == PPC::CNTLZW || Opcode == PPC::CNTLZW_rec ||
254 Opcode == PPC::CNTTZW || Opcode == PPC::CNTTZW_rec ||
255 Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8)
259 if (Opcode == PPC::CNTLZD || Opcode == PPC::CNTLZD_rec ||
260 Opcode == PPC::CNTTZD || Opcode == PPC::CNTTZD_rec)
264 if (Opcode == PPC::LHZ || Opcode == PPC::LHZX ||
265 Opcode == PPC::LHZ8 || Opcode == PPC::LHZX8 ||
266 Opcode == PPC::LHZU || Opcode == PPC::LHZUX ||
267 Opcode == PPC::LHZU8 || Opcode == PPC::LHZUX8)
270 if (Opcode == PPC::LBZ || Opcode == PPC::LBZX ||
271 Opcode == PPC::LBZ8 || Opcode == PPC::LBZX8 ||
272 Opcode == PPC::LBZU || Opcode == PPC::LBZUX ||
273 Opcode == PPC::LBZU8 || Opcode == PPC::LBZUX8)
276 if (Opcode == PPC::AND || Opcode == PPC::AND8 || Opcode == PPC::AND_rec ||
277 Opcode == PPC::AND8_rec)
279 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
280 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
282 if (Opcode == PPC::OR || Opcode == PPC::OR8 || Opcode == PPC::XOR ||
283 Opcode == PPC::XOR8 || Opcode == PPC::OR_rec ||
284 Opcode == PPC::OR8_rec || Opcode == PPC::XOR_rec ||
285 Opcode == PPC::XOR8_rec)
287 getKnownLeadingZeroCount(
MI->getOperand(1).getReg(),
TII,
MRI),
288 getKnownLeadingZeroCount(
MI->getOperand(2).getReg(),
TII,
MRI));
290 if (
TII->isZeroExtended(Reg,
MRI))
302void PPCMIPeephole::UpdateTOCSaves(
304 assert(
TII->isTOCSaveMI(*
MI) &&
"Expecting a TOC save instruction here");
317 if (CurrBlockFreq > EntryFreq || MPDT->
dominates(
MI->getParent(), Entry))
323 for (
auto &TOCSave : TOCSaves)
324 TOCSave.second =
false;
326 TOCSaves[
MI] =
false;
332 for (
auto &
I : TOCSaves) {
358 unsigned VisitedIndex = 0;
359 while (VisitedIndex < PHIs.
size()) {
362 PHIOp != NumOps; PHIOp += 2) {
369 unsigned Opcode =
Instr->getOpcode();
370 if (Opcode == PPC::COPY) {
372 if (!
Reg.isVirtual() ||
MRI->getRegClass(Reg) != &PPC::ACCRCRegClass)
374 }
else if (Opcode != PPC::IMPLICIT_DEF && Opcode != PPC::PHI)
380 if (Opcode != PPC::PHI)
395void PPCMIPeephole::convertUnprimedAccPHIs(
405 for (
unsigned PHIOp = 1, NumOps =
PHI->getNumOperands(); PHIOp != NumOps;
410 assert((Opcode == PPC::COPY || Opcode == PPC::IMPLICIT_DEF ||
411 Opcode == PPC::PHI) &&
412 "Unexpected instruction");
413 if (Opcode == PPC::COPY) {
415 &PPC::ACCRCRegClass &&
416 "Unexpected register class");
418 }
else if (Opcode == PPC::IMPLICIT_DEF) {
419 Register AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
421 TII->get(PPC::IMPLICIT_DEF), AccReg);
423 PHI->getOperand(PHIOp + 1)});
424 }
else if (Opcode == PPC::PHI) {
429 "This PHI node should have already been changed.");
433 PHI->getOperand(PHIOp + 1)});
443 AccReg =
MRI->createVirtualRegister(&PPC::ACCRCRegClass);
445 *
PHI->getParent(),
PHI,
PHI->getDebugLoc(),
TII->get(PPC::PHI), AccReg);
446 for (
auto RegMBB : PHIOps) {
447 NewPHI.
add(RegMBB.first).
add(RegMBB.second);
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())
1294 ++NumRotatesCollapsed;
1307 bool IsOperand2Immediate =
MI.getOperand(2).isImm();
1310 if (!(LiMI1 && (LiMI1->
getOpcode() == PPC::LI ||
1313 if (!IsOperand2Immediate &&
1314 !(LiMI2 && (LiMI2->
getOpcode() == PPC::LI ||
1318 auto ImmOperand0 =
MI.getOperand(0).getImm();
1320 auto ImmOperand2 = IsOperand2Immediate ?
MI.getOperand(2).getImm()
1325 if ((ImmOperand0 == 31) ||
1326 ((ImmOperand0 & 0x10) &&
1327 ((int64_t)ImmOperand1 < (int64_t)ImmOperand2)) ||
1328 ((ImmOperand0 & 0x8) &&
1329 ((int64_t)ImmOperand1 > (int64_t)ImmOperand2)) ||
1330 ((ImmOperand0 & 0x2) &&
1332 ((ImmOperand0 & 0x1) &&
1334 ((ImmOperand0 & 0x4) && (ImmOperand1 == ImmOperand2))) {
1349 recomputeLVForDyingInstr();
1359 Simplified |= eliminateRedundantTOCSaves(TOCSaves);
1362 NumTOCSavesInPrologue++;
1370 for (
Register Reg : RegsToUpdate) {
1371 if (!
MRI->reg_empty(Reg))
1384static bool isSupportedCmpOp(
unsigned opCode) {
1385 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1386 opCode == PPC::CMPLW || opCode == PPC::CMPW ||
1387 opCode == PPC::CMPLDI || opCode == PPC::CMPDI ||
1388 opCode == PPC::CMPLWI || opCode == PPC::CMPWI);
1391static bool is64bitCmpOp(
unsigned opCode) {
1392 return (opCode == PPC::CMPLD || opCode == PPC::CMPD ||
1393 opCode == PPC::CMPLDI || opCode == PPC::CMPDI);
1396static bool isSignedCmpOp(
unsigned opCode) {
1397 return (opCode == PPC::CMPD || opCode == PPC::CMPW ||
1398 opCode == PPC::CMPDI || opCode == PPC::CMPWI);
1401static unsigned getSignedCmpOpCode(
unsigned opCode) {
1402 if (opCode == PPC::CMPLD)
return PPC::CMPD;
1403 if (opCode == PPC::CMPLW)
return PPC::CMPW;
1404 if (opCode == PPC::CMPLDI)
return PPC::CMPDI;
1405 if (opCode == PPC::CMPLWI)
return PPC::CMPWI;
1413 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1414 if ((!SignedCmp && Imm == 0) || (SignedCmp && Imm == 0x8000))
1432 bool SignedCmp = isSignedCmpOp(
CMPI->getOpcode());
1433 if ((!SignedCmp && Imm == 0xFFFF) || (SignedCmp && Imm == 0x7FFF))
1448static unsigned getIncomingRegForBlock(
MachineInstr *Phi,
1450 for (
unsigned I = 2, E =
Phi->getNumOperands() + 1;
I != E;
I += 2) {
1453 return Phi->getOperand(
I-1).getReg();
1464 unsigned SrcReg =
Reg;
1466 unsigned NextReg = SrcReg;
1469 NextReg = getIncomingRegForBlock(Inst, BB1);
1488 auto BII = BB.getFirstInstrTerminator();
1492 if (BB.succ_size() == 2 &&
1493 BII != BB.instr_end() &&
1494 (*BII).getOpcode() == PPC::BCC &&
1495 (*BII).getOperand(1).isReg()) {
1497 Register CndReg = (*BII).getOperand(1).getReg();
1498 if (!CndReg.
isVirtual() || !
MRI->hasOneNonDBGUse(CndReg))
1503 if (
CMPI->getParent() != &BB)
1521 return BB.succ_size() == 1;
1524 if (!isEligibleBB(
MBB))
1528 if (NumPredBBs == 1) {
1530 if (isEligibleBB(*TmpMBB)) {
1532 MBBtoMoveCmp =
nullptr;
1536 else if (NumPredBBs == 2) {
1544 if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
1549 else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
1555 if (Pred1MBB == &
MBB)
1563 for (
int I = 1;
I <= 2;
I++)
1564 if (
CMPI->getOperand(
I).isReg()) {
1571 MBBtoMoveCmp = Pred2MBB;
1582bool PPCMIPeephole::eliminateRedundantTOCSaves(
1583 std::map<MachineInstr *, bool> &TOCSaves) {
1586 for (
auto TOCSave : TOCSaves) {
1587 if (!TOCSave.second) {
1588 TOCSave.first->eraseFromParent();
1624bool PPCMIPeephole::eliminateRedundantCompare() {
1657 if (!eligibleForCompareElimination(MBB2, MBB1, MBBtoMoveCmp,
MRI))
1665 bool IsPartiallyRedundant = (MBBtoMoveCmp !=
nullptr);
1669 if (!isSupportedCmpOp(CMPI1->
getOpcode()) ||
1670 !isSupportedCmpOp(CMPI2->
getOpcode()) ||
1674 unsigned NewOpCode = 0;
1675 unsigned NewPredicate1 = 0, NewPredicate2 = 0;
1677 bool SwapOperands =
false;
1689 if (!
I->getOperand(2).isImm())
1691 int16_t
Imm = (int16_t)
I->getOperand(2).getImm();
1695 if (isEqOrNe(BI2) && !CmpAgainstImmWithSignBit(CMPI2) &&
1698 else if (isEqOrNe(BI1) && !CmpAgainstImmWithSignBit(CMPI1) &&
1708 nullptr,
nullptr,
MRI);
1710 nullptr,
nullptr,
MRI);
1716 if (Cmp1Operand1 == Cmp2Operand1 && Cmp1Operand2 == Cmp2Operand2) {
1719 else if (Cmp1Operand1 == Cmp2Operand2 && Cmp1Operand2 == Cmp2Operand1) {
1726 SwapOperands =
true;
1734 nullptr,
nullptr,
MRI);
1737 if (Cmp1Operand1 != Cmp2Operand1)
1745 if (Imm1 != Imm2 && (!isEqOrNe(BI2) || !isEqOrNe(BI1))) {
1746 int Diff = Imm1 - Imm2;
1747 if (Diff < -2 || Diff > 2)
1750 unsigned PredToInc1 = getPredicateToIncImm(BI1, CMPI1);
1751 unsigned PredToDec1 = getPredicateToDecImm(BI1, CMPI1);
1752 unsigned PredToInc2 = getPredicateToIncImm(BI2, CMPI2);
1753 unsigned PredToDec2 = getPredicateToDecImm(BI2, CMPI2);
1755 if (PredToInc2 && PredToDec1) {
1756 NewPredicate2 = PredToInc2;
1757 NewPredicate1 = PredToDec1;
1762 else if (Diff == 1) {
1765 NewPredicate2 = PredToInc2;
1767 else if (PredToDec1) {
1769 NewPredicate1 = PredToDec1;
1772 else if (Diff == -1) {
1775 NewPredicate2 = PredToDec2;
1777 else if (PredToInc1) {
1779 NewPredicate1 = PredToInc1;
1782 else if (Diff == -2) {
1783 if (PredToDec2 && PredToInc1) {
1784 NewPredicate2 = PredToDec2;
1785 NewPredicate1 = PredToInc1;
1797 LLVM_DEBUG(
dbgs() <<
"Optimize two pairs of compare and branch:\n");
1810 if (NewOpCode != 0 && NewOpCode != CMPI1->
getOpcode()) {
1813 if (NewPredicate1) {
1816 if (NewPredicate2) {
1823 if (IsPartiallyRedundant) {
1835 for (
int I = 1;
I <= 2;
I++) {
1842 "We cannot support if an operand comes from this BB.");
1843 unsigned SrcReg = getIncomingRegForBlock(Inst, MBBtoMoveCmp);
1852 Register NewVReg =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
1854 TII->get(PPC::PHI), NewVReg)
1877 if (IsPartiallyRedundant) {
1880 <<
" to handle partial redundancy.\n");
1892bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(
MachineInstr &
MI,
1894 if (
MI.getOpcode() != PPC::RLDICR)
1919 if (NewMB > 63 || NewSH > 63)
1928 if ((63 - NewSH) != MEMI)
1935 MI.setDesc(
TII->get(PPC::RLDIC));
1937 MI.getOperand(2).setImm(NewSH);
1938 MI.getOperand(3).setImm(NewMB);
1944 NumRotatesCollapsed++;
1946 if (
MRI->use_nodbg_empty(SrcReg)) {
1948 "Not expecting an implicit def with this instr.");
1967 if (
MI.getOpcode() != PPC::RLDICR)
1973 assert(
MI.getNumOperands() == 4 &&
"RLDICR should have 4 operands");
1982 if (SHMI + MEMI != 63)
1996 if (!
MRI->hasOneNonDBGUse(SrcReg))
2001 "EXTSW's second operand should be a register");
2011 SrcMI->
getOpcode() == PPC::EXTSW ?
TII->get(PPC::EXTSWSLI)
2012 :
TII->get(PPC::EXTSWSLI_32_64),
2013 MI.getOperand(0).getReg())
2020 ++NumEXTSWAndSLDICombined;
2033 "PowerPC MI Peephole Optimization",
false,
false)
2041char PPCMIPeephole::
ID = 0;
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define addRegToUpdate(R)
PowerPC MI Peephole Optimization
static cl::opt< bool > EnableZExtElimination("ppc-eliminate-zeroext", cl::desc("enable elimination of zero-extensions"), cl::init(true), cl::Hidden)
static cl::opt< bool > FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true), cl::desc("Iterate to a fixed point when attempting to " "convert reg-reg instructions to reg-imm"))
static cl::opt< bool > EnableTrapOptimization("ppc-opt-conditional-trap", cl::desc("enable optimization of conditional traps"), cl::init(false), cl::Hidden)
static cl::opt< bool > ConvertRegReg("ppc-convert-rr-to-ri", cl::Hidden, cl::init(true), cl::desc("Convert eligible reg+reg instructions to reg+imm"))
static cl::opt< bool > EnableSExtElimination("ppc-eliminate-signext", cl::desc("enable elimination of sign-extensions"), cl::init(true), cl::Hidden)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
static bool shouldExecute(unsigned CounterName)
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
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...
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.
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.