diff options
| author | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-03-05 19:27:16 +0000 |
|---|---|---|
| committer | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2018-03-05 19:27:16 +0000 |
| commit | 6cc31ca81446b3fc61e02e2c231436978746decd (patch) | |
| tree | 0b0f5df8546c7ed7475b83d4b1e28ade79af0cb5 /llvm/lib/Target/PowerPC | |
| parent | 77ae82b84a451f1a3af878da1a4efb5fb0a043b6 (diff) | |
| download | bcm5719-llvm-6cc31ca81446b3fc61e02e2c231436978746decd.tar.gz bcm5719-llvm-6cc31ca81446b3fc61e02e2c231436978746decd.zip | |
[PowerPC] Do not emit record-form rotates when record-form andi suffices
Up until Power9, the performance profile for rlwinm., rldicl. and andi. looked
more or less equivalent. However with Power9, the rotates are still 2-way
cracked whereas the and-immediate is not.
This patch just ensures that we don't emit record-form rotates when an andi.
is adequate.
As first pointed out by Carrot in https://bugs.llvm.org/show_bug.cgi?id=30833
(this patch is a fix for that PR).
Differential Revision: https://reviews.llvm.org/D43977
llvm-svn: 326736
Diffstat (limited to 'llvm/lib/Target/PowerPC')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index ec74d309f68..4e0dd9d5e5e 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -55,6 +55,8 @@ STATISTIC(CmpIselsConverted, "Number of ISELs that depend on comparison of constants converted"); STATISTIC(MissedConvertibleImmediateInstrs, "Number of compare-immediate instructions fed by constants"); +STATISTIC(NumRcRotatesConvertedToRcAnd, + "Number of record-form rotates converted to record-form andi"); static cl:: opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, @@ -1897,6 +1899,31 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, // specifically the case if this is the instruction directly after the // compare). + // Rotates are expensive instructions. If we're emitting a record-form + // rotate that can just be an andi, we should just emit the andi. + if ((MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) && + MI->getOperand(2).getImm() == 0) { + int64_t MB = MI->getOperand(3).getImm(); + int64_t ME = MI->getOperand(4).getImm(); + if (MB < ME && MB >= 16) { + uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1); + NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIo : PPC::ANDIo8; + MI->RemoveOperand(4); + MI->RemoveOperand(3); + MI->getOperand(2).setImm(Mask); + NumRcRotatesConvertedToRcAnd++; + } + } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) { + int64_t MB = MI->getOperand(3).getImm(); + if (MB >= 48) { + uint64_t Mask = (1LLU << (63 - MB + 1)) - 1; + NewOpC = PPC::ANDIo8; + MI->RemoveOperand(3); + MI->getOperand(2).setImm(Mask); + NumRcRotatesConvertedToRcAnd++; + } + } + const MCInstrDesc &NewDesc = get(NewOpC); MI->setDesc(NewDesc); |

