diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 74192cb20cd0..d2aba6bd6e8d 100644 --- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -57,6 +57,8 @@ STATISTIC(NumRotatesCollapsed, "Number of pairs of rotate left, clear left/right collapsed"); STATISTIC(NumEXTSWAndSLDICombined, "Number of pairs of EXTSW and SLDI combined as EXTSWSLI"); +STATISTIC(NumLoadImmZeroFoldedAndRemoved, + "Number of LI(8) reg, 0 that are folded to r0 and removed"); static cl::opt<bool> FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true), @@ -124,9 +126,14 @@ public: // Main entry point for this pass. bool runOnMachineFunction(MachineFunction &MF) override { + initialize(MF); + // At this point, TOC pointer should not be used in a function that uses + // PC-Relative addressing. + assert((MF.getRegInfo().use_empty(PPC::X2) || + !MF.getSubtarget<PPCSubtarget>().isUsingPCRelativeCalls()) && + "TOC pointer used in a function using PC-Relative addressing!"); if (skipFunction(MF.getFunction())) return false; - initialize(MF); return simplifyCode(); } }; @@ -314,7 +321,22 @@ bool PPCMIPeephole::simplifyCode(void) { default: break; - + case PPC::LI: + case PPC::LI8: { + // If we are materializing a zero, look for any use operands for which + // zero means immediate zero. All such operands can be replaced with + // PPC::ZERO. + if (!MI.getOperand(1).isImm() || MI.getOperand(1).getImm() != 0) + break; + unsigned MIDestReg = MI.getOperand(0).getReg(); + for (MachineInstr& UseMI : MRI->use_instructions(MIDestReg)) + Simplified |= TII->onlyFoldImmediate(UseMI, MI, MIDestReg); + if (MRI->use_nodbg_empty(MIDestReg)) { + ++NumLoadImmZeroFoldedAndRemoved; + ToErase = &MI; + } + break; + } case PPC::STD: { MachineFrameInfo &MFI = MF->getFrameInfo(); if (MFI.hasVarSizedObjects() || @@ -541,10 +563,12 @@ bool PPCMIPeephole::simplifyCode(void) { if (!P1 || !P2) break; - // Remove the passed FRSP instruction if it only feeds this MI and - // set any uses of that FRSP (in this MI) to the source of the FRSP. + // Remove the passed FRSP/XSRSP instruction if it only feeds this MI + // and set any uses of that FRSP/XSRSP (in this MI) to the source of + // the FRSP/XSRSP. auto removeFRSPIfPossible = [&](MachineInstr *RoundInstr) { - if (RoundInstr->getOpcode() == PPC::FRSP && + unsigned Opc = RoundInstr->getOpcode(); + if ((Opc == PPC::FRSP || Opc == PPC::XSRSP) && MRI->hasOneNonDBGUse(RoundInstr->getOperand(0).getReg())) { Simplified = true; Register ConvReg1 = RoundInstr->getOperand(1).getReg(); @@ -554,7 +578,7 @@ bool PPCMIPeephole::simplifyCode(void) { if (Use.getOperand(i).isReg() && Use.getOperand(i).getReg() == FRSPDefines) Use.getOperand(i).setReg(ConvReg1); - LLVM_DEBUG(dbgs() << "Removing redundant FRSP:\n"); + LLVM_DEBUG(dbgs() << "Removing redundant FRSP/XSRSP:\n"); LLVM_DEBUG(RoundInstr->dump()); LLVM_DEBUG(dbgs() << "As it feeds instruction:\n"); LLVM_DEBUG(MI.dump()); @@ -882,11 +906,6 @@ bool PPCMIPeephole::simplifyCode(void) { // while in PowerPC ISA, lowerest bit is at index 63. APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc); - // Current APInt::getBitsSetWithWrap sets all bits to 0 if loBit is - // equal to highBit. - // If MBSrc - MESrc == 1, we expect a full set mask instead of Null. - if (SrcMaskFull && (MBSrc - MESrc == 1)) - MaskSrc.setAllBits(); APInt RotatedSrcMask = MaskSrc.rotl(SHMI); APInt FinalMask = RotatedSrcMask & MaskMI; @@ -1540,6 +1559,12 @@ bool PPCMIPeephole::emitRLDICWhenLoweringJumpTables(MachineInstr &MI) { LLVM_DEBUG(dbgs() << "To: "); LLVM_DEBUG(MI.dump()); NumRotatesCollapsed++; + // If SrcReg has no non-debug use it's safe to delete its def SrcMI. + if (MRI->use_nodbg_empty(SrcReg)) { + assert(!SrcMI->hasImplicitDef() && + "Not expecting an implicit def with this instr."); + SrcMI->eraseFromParent(); + } return true; } |