summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC
diff options
context:
space:
mode:
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>2018-03-05 19:27:16 +0000
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>2018-03-05 19:27:16 +0000
commit6cc31ca81446b3fc61e02e2c231436978746decd (patch)
tree0b0f5df8546c7ed7475b83d4b1e28ade79af0cb5 /llvm/lib/Target/PowerPC
parent77ae82b84a451f1a3af878da1a4efb5fb0a043b6 (diff)
downloadbcm5719-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.cpp27
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);
OpenPOWER on IntegriCloud