summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCMIPeephole.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/PowerPC/PPCMIPeephole.cpp')
-rw-r--r--lib/Target/PowerPC/PPCMIPeephole.cpp111
1 files changed, 63 insertions, 48 deletions
diff --git a/lib/Target/PowerPC/PPCMIPeephole.cpp b/lib/Target/PowerPC/PPCMIPeephole.cpp
index 2f44b8c13a3..45647a2c36b 100644
--- a/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -41,6 +41,22 @@ STATISTIC(MultiTOCSaves,
STATISTIC(NumEliminatedSExt, "Number of eliminated sign-extensions");
STATISTIC(NumEliminatedZExt, "Number of eliminated zero-extensions");
STATISTIC(NumOptADDLIs, "Number of optimized ADD instruction fed by LI");
+STATISTIC(NumConvertedToImmediateForm,
+ "Number of instructions converted to their immediate form");
+STATISTIC(NumFunctionsEnteredInMIPeephole,
+ "Number of functions entered in PPC MI Peepholes");
+STATISTIC(NumFixedPointIterations,
+ "Number of fixed-point iterations converting reg-reg instructions "
+ "to reg-imm ones");
+
+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>
+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",
@@ -52,10 +68,6 @@ static cl::opt<bool>
cl::desc("enable elimination of zero-extensions"),
cl::init(false), cl::Hidden);
-namespace llvm {
- void initializePPCMIPeepholePass(PassRegistry&);
-}
-
namespace {
struct PPCMIPeephole : public MachineFunctionPass {
@@ -83,9 +95,6 @@ private:
bool eliminateRedundantTOCSaves(std::map<MachineInstr *, bool> &TOCSaves);
void UpdateTOCSaves(std::map<MachineInstr *, bool> &TOCSaves,
MachineInstr *MI);
- // Find the "true" register represented by SrcReg (following chains
- // of copies and subreg_to_reg operations).
- unsigned lookThruCopyLike(unsigned SrcReg);
public:
@@ -212,6 +221,35 @@ bool PPCMIPeephole::simplifyCode(void) {
MachineInstr* ToErase = nullptr;
std::map<MachineInstr *, bool> TOCSaves;
+ NumFunctionsEnteredInMIPeephole++;
+ if (ConvertRegReg) {
+ // Fixed-point conversion of reg/reg instructions fed by load-immediate
+ // into reg/imm instructions. FIXME: This is expensive, control it with
+ // an option.
+ bool SomethingChanged = false;
+ do {
+ NumFixedPointIterations++;
+ SomethingChanged = false;
+ for (MachineBasicBlock &MBB : *MF) {
+ for (MachineInstr &MI : MBB) {
+ if (MI.isDebugValue())
+ continue;
+
+ if (TII->convertToImmediateForm(MI)) {
+ // We don't erase anything in case the def has other uses. Let DCE
+ // remove it if it can be removed.
+ DEBUG(dbgs() << "Converted instruction to imm form: ");
+ DEBUG(MI.dump());
+ NumConvertedToImmediateForm++;
+ SomethingChanged = true;
+ Simplified = true;
+ continue;
+ }
+ }
+ }
+ } while (SomethingChanged && FixedPointRegToImm);
+ }
+
for (MachineBasicBlock &MBB : *MF) {
for (MachineInstr &MI : MBB) {
@@ -258,8 +296,10 @@ bool PPCMIPeephole::simplifyCode(void) {
// XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), immed.
// We have to look through chains of COPY and SUBREG_TO_REG
// to find the real source values for comparison.
- unsigned TrueReg1 = lookThruCopyLike(MI.getOperand(1).getReg());
- unsigned TrueReg2 = lookThruCopyLike(MI.getOperand(2).getReg());
+ unsigned TrueReg1 =
+ TII->lookThruCopyLike(MI.getOperand(1).getReg(), MRI);
+ unsigned TrueReg2 =
+ TII->lookThruCopyLike(MI.getOperand(2).getReg(), MRI);
if (TrueReg1 == TrueReg2
&& TargetRegisterInfo::isVirtualRegister(TrueReg1)) {
@@ -273,7 +313,8 @@ bool PPCMIPeephole::simplifyCode(void) {
auto isConversionOfLoadAndSplat = [=]() -> bool {
if (DefOpc != PPC::XVCVDPSXDS && DefOpc != PPC::XVCVDPUXDS)
return false;
- unsigned DefReg = lookThruCopyLike(DefMI->getOperand(1).getReg());
+ unsigned DefReg =
+ TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI);
if (TargetRegisterInfo::isVirtualRegister(DefReg)) {
MachineInstr *LoadMI = MRI->getVRegDef(DefReg);
if (LoadMI && LoadMI->getOpcode() == PPC::LXVDSX)
@@ -299,10 +340,10 @@ bool PPCMIPeephole::simplifyCode(void) {
// can replace it with a copy.
if (DefOpc == PPC::XXPERMDI) {
unsigned FeedImmed = DefMI->getOperand(3).getImm();
- unsigned FeedReg1
- = lookThruCopyLike(DefMI->getOperand(1).getReg());
- unsigned FeedReg2
- = lookThruCopyLike(DefMI->getOperand(2).getReg());
+ unsigned FeedReg1 =
+ TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI);
+ unsigned FeedReg2 =
+ TII->lookThruCopyLike(DefMI->getOperand(2).getReg(), MRI);
if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {
DEBUG(dbgs()
@@ -360,7 +401,8 @@ bool PPCMIPeephole::simplifyCode(void) {
case PPC::XXSPLTW: {
unsigned MyOpcode = MI.getOpcode();
unsigned OpNo = MyOpcode == PPC::XXSPLTW ? 1 : 2;
- unsigned TrueReg = lookThruCopyLike(MI.getOperand(OpNo).getReg());
+ unsigned TrueReg =
+ TII->lookThruCopyLike(MI.getOperand(OpNo).getReg(), MRI);
if (!TargetRegisterInfo::isVirtualRegister(TrueReg))
break;
MachineInstr *DefMI = MRI->getVRegDef(TrueReg);
@@ -422,7 +464,8 @@ bool PPCMIPeephole::simplifyCode(void) {
}
case PPC::XVCVDPSP: {
// If this is a DP->SP conversion fed by an FRSP, the FRSP is redundant.
- unsigned TrueReg = lookThruCopyLike(MI.getOperand(1).getReg());
+ unsigned TrueReg =
+ TII->lookThruCopyLike(MI.getOperand(1).getReg(), MRI);
if (!TargetRegisterInfo::isVirtualRegister(TrueReg))
break;
MachineInstr *DefMI = MRI->getVRegDef(TrueReg);
@@ -430,8 +473,10 @@ bool PPCMIPeephole::simplifyCode(void) {
// This can occur when building a vector of single precision or integer
// values.
if (DefMI && DefMI->getOpcode() == PPC::XXPERMDI) {
- unsigned DefsReg1 = lookThruCopyLike(DefMI->getOperand(1).getReg());
- unsigned DefsReg2 = lookThruCopyLike(DefMI->getOperand(2).getReg());
+ unsigned DefsReg1 =
+ TII->lookThruCopyLike(DefMI->getOperand(1).getReg(), MRI);
+ unsigned DefsReg2 =
+ TII->lookThruCopyLike(DefMI->getOperand(2).getReg(), MRI);
if (!TargetRegisterInfo::isVirtualRegister(DefsReg1) ||
!TargetRegisterInfo::isVirtualRegister(DefsReg2))
break;
@@ -1221,36 +1266,6 @@ bool PPCMIPeephole::eliminateRedundantCompare(void) {
return Simplified;
}
-// This is used to find the "true" source register for an
-// XXPERMDI instruction, since MachineCSE does not handle the
-// "copy-like" operations (Copy and SubregToReg). Returns
-// the original SrcReg unless it is the target of a copy-like
-// operation, in which case we chain backwards through all
-// such operations to the ultimate source register. If a
-// physical register is encountered, we stop the search.
-unsigned PPCMIPeephole::lookThruCopyLike(unsigned SrcReg) {
-
- while (true) {
-
- MachineInstr *MI = MRI->getVRegDef(SrcReg);
- if (!MI->isCopyLike())
- return SrcReg;
-
- unsigned CopySrcReg;
- if (MI->isCopy())
- CopySrcReg = MI->getOperand(1).getReg();
- else {
- assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike");
- CopySrcReg = MI->getOperand(2).getReg();
- }
-
- if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg))
- return CopySrcReg;
-
- SrcReg = CopySrcReg;
- }
-}
-
} // end default namespace
INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE,