summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>2019-06-05 02:36:40 +0000
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>2019-06-05 02:36:40 +0000
commit7c842fadf100b2ed160986e40a9a68a0613df256 (patch)
treeda5a2d10def877529cd9f745e604cd7181ec6b6d /llvm/lib/Target
parent44fb55bf96158ac3c9a90eae1818fb6b1ddefef6 (diff)
downloadbcm5719-llvm-7c842fadf100b2ed160986e40a9a68a0613df256.tar.gz
bcm5719-llvm-7c842fadf100b2ed160986e40a9a68a0613df256.zip
[PowerPC] Collapse RLDICL/RLDICR into RLDIC when possible
Generally speaking, we lower to an optimal rotate sequence for nodes visible in the SDAG. However, there are instances where the two rotates are not visible at ISEL time - most notably those in a very common sequence when lowering switch statements to jump tables. A common situation is a switch on a 32-bit integer. This value has to have the upper 32 bits cleared and because jump table offsets are word offsets, the value needs to be shifted left by 2 bits. We currently emit the clear and the left shift as two separate instructions, but this is not needed as we can lower it to a single RLDIC. This patch just cleans that up. Differential revision: https://reviews.llvm.org/D60402 llvm-svn: 362576
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/PowerPC/PPCMIPeephole.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
index 255ba2d8681..9a566eddfdd 100644
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -47,6 +47,8 @@ STATISTIC(NumFunctionsEnteredInMIPeephole,
STATISTIC(NumFixedPointIterations,
"Number of fixed-point iterations converting reg-reg instructions "
"to reg-imm ones");
+STATISTIC(NumRotatesCollapsed,
+ "Number of pairs of rotate left, clear left/right collapsed");
static cl::opt<bool>
FixedPointRegToImm("ppc-reg-to-imm-fixed-point", cl::Hidden, cl::init(true),
@@ -757,6 +759,56 @@ bool PPCMIPeephole::simplifyCode(void) {
NumOptADDLIs++;
break;
}
+ case PPC::RLDICR: {
+ // We miss the opportunity to emit an RLDIC when lowering jump tables
+ // since ISEL sees only a single basic block. When selecting, the clear
+ // and shift left will be in different blocks.
+ unsigned SrcReg = MI.getOperand(1).getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
+ break;
+
+ MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
+ if (SrcMI->getOpcode() != PPC::RLDICL)
+ break;
+ MachineOperand MOpSHSrc = SrcMI->getOperand(2);
+ MachineOperand MOpMBSrc = SrcMI->getOperand(3);
+ MachineOperand MOpSHMI = MI.getOperand(2);
+ MachineOperand MOpMEMI = MI.getOperand(3);
+ if (!(MOpSHSrc.isImm() && MOpMBSrc.isImm() &&
+ MOpSHMI.isImm() && MOpMEMI.isImm()))
+ break;
+ uint64_t SHSrc = MOpSHSrc.getImm();
+ uint64_t MBSrc = MOpMBSrc.getImm();
+ uint64_t SHMI = MOpSHMI.getImm();
+ uint64_t MEMI = MOpMEMI.getImm();
+ uint64_t NewSH = SHSrc + SHMI;
+ uint64_t NewMB = MBSrc - SHMI;
+ if (NewMB > 63 || NewSH > 63)
+ break;
+
+ // The bits cleared with RLDICL are [0, MBSrc).
+ // The bits cleared with RLDICR are (MEMI, 63].
+ // After the sequence, the bits cleared are:
+ // [0, MBSrc-SHMI) and (MEMI, 63).
+ //
+ // The bits cleared with RLDIC are [0, NewMB) and (63-NewSH, 63].
+ if ((63 - NewSH) != MEMI)
+ break;
+
+ LLVM_DEBUG(dbgs() << "Converting pair: ");
+ LLVM_DEBUG(SrcMI->dump());
+ LLVM_DEBUG(MI.dump());
+
+ MI.setDesc(TII->get(PPC::RLDIC));
+ MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
+ MI.getOperand(2).setImm(NewSH);
+ MI.getOperand(3).setImm(NewMB);
+
+ LLVM_DEBUG(dbgs() << "To: ");
+ LLVM_DEBUG(MI.dump());
+ NumRotatesCollapsed++;
+ break;
+ }
}
}
OpenPOWER on IntegriCloud