Home | History | Annotate | Download | only in PowerPC
      1 //===-------------- PPCMIPeephole.cpp - MI Peephole Cleanups -------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===---------------------------------------------------------------------===//
      9 //
     10 // This pass performs peephole optimizations to clean up ugly code
     11 // sequences at the MachineInstruction layer.  It runs at the end of
     12 // the SSA phases, following VSX swap removal.  A pass of dead code
     13 // elimination follows this one for quick clean-up of any dead
     14 // instructions introduced here.  Although we could do this as callbacks
     15 // from the generic peephole pass, this would have a couple of bad
     16 // effects:  it might remove optimization opportunities for VSX swap
     17 // removal, and it would miss cleanups made possible following VSX
     18 // swap removal.
     19 //
     20 //===---------------------------------------------------------------------===//
     21 
     22 #include "PPCInstrInfo.h"
     23 #include "PPC.h"
     24 #include "PPCInstrBuilder.h"
     25 #include "PPCTargetMachine.h"
     26 #include "llvm/CodeGen/MachineFunctionPass.h"
     27 #include "llvm/CodeGen/MachineInstrBuilder.h"
     28 #include "llvm/CodeGen/MachineRegisterInfo.h"
     29 #include "llvm/Support/Debug.h"
     30 
     31 using namespace llvm;
     32 
     33 #define DEBUG_TYPE "ppc-mi-peepholes"
     34 
     35 namespace llvm {
     36   void initializePPCMIPeepholePass(PassRegistry&);
     37 }
     38 
     39 namespace {
     40 
     41 struct PPCMIPeephole : public MachineFunctionPass {
     42 
     43   static char ID;
     44   const PPCInstrInfo *TII;
     45   MachineFunction *MF;
     46   MachineRegisterInfo *MRI;
     47 
     48   PPCMIPeephole() : MachineFunctionPass(ID) {
     49     initializePPCMIPeepholePass(*PassRegistry::getPassRegistry());
     50   }
     51 
     52 private:
     53   // Initialize class variables.
     54   void initialize(MachineFunction &MFParm);
     55 
     56   // Perform peepholes.
     57   bool simplifyCode(void);
     58 
     59   // Find the "true" register represented by SrcReg (following chains
     60   // of copies and subreg_to_reg operations).
     61   unsigned lookThruCopyLike(unsigned SrcReg);
     62 
     63 public:
     64   // Main entry point for this pass.
     65   bool runOnMachineFunction(MachineFunction &MF) override {
     66     initialize(MF);
     67     return simplifyCode();
     68   }
     69 };
     70 
     71 // Initialize class variables.
     72 void PPCMIPeephole::initialize(MachineFunction &MFParm) {
     73   MF = &MFParm;
     74   MRI = &MF->getRegInfo();
     75   TII = MF->getSubtarget<PPCSubtarget>().getInstrInfo();
     76   DEBUG(dbgs() << "*** PowerPC MI peephole pass ***\n\n");
     77   DEBUG(MF->dump());
     78 }
     79 
     80 // Perform peephole optimizations.
     81 bool PPCMIPeephole::simplifyCode(void) {
     82   bool Simplified = false;
     83   MachineInstr* ToErase = nullptr;
     84 
     85   for (MachineBasicBlock &MBB : *MF) {
     86     for (MachineInstr &MI : MBB) {
     87 
     88       // If the previous instruction was marked for elimination,
     89       // remove it now.
     90       if (ToErase) {
     91         ToErase->eraseFromParent();
     92         ToErase = nullptr;
     93       }
     94 
     95       // Ignore debug instructions.
     96       if (MI.isDebugValue())
     97         continue;
     98 
     99       // Per-opcode peepholes.
    100       switch (MI.getOpcode()) {
    101 
    102       default:
    103         break;
    104 
    105       case PPC::XXPERMDI: {
    106         // Perform simplifications of 2x64 vector swaps and splats.
    107         // A swap is identified by an immediate value of 2, and a splat
    108         // is identified by an immediate value of 0 or 3.
    109         int Immed = MI.getOperand(3).getImm();
    110 
    111         if (Immed != 1) {
    112 
    113           // For each of these simplifications, we need the two source
    114           // regs to match.  Unfortunately, MachineCSE ignores COPY and
    115           // SUBREG_TO_REG, so for example we can see
    116           //   XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), immed.
    117           // We have to look through chains of COPY and SUBREG_TO_REG
    118           // to find the real source values for comparison.
    119           unsigned TrueReg1 = lookThruCopyLike(MI.getOperand(1).getReg());
    120           unsigned TrueReg2 = lookThruCopyLike(MI.getOperand(2).getReg());
    121 
    122           if (TrueReg1 == TrueReg2
    123               && TargetRegisterInfo::isVirtualRegister(TrueReg1)) {
    124             MachineInstr *DefMI = MRI->getVRegDef(TrueReg1);
    125 
    126             // If this is a splat or a swap fed by another splat, we
    127             // can replace it with a copy.
    128             if (DefMI && DefMI->getOpcode() == PPC::XXPERMDI) {
    129               unsigned FeedImmed = DefMI->getOperand(3).getImm();
    130               unsigned FeedReg1
    131                 = lookThruCopyLike(DefMI->getOperand(1).getReg());
    132               unsigned FeedReg2
    133                 = lookThruCopyLike(DefMI->getOperand(2).getReg());
    134 
    135               if ((FeedImmed == 0 || FeedImmed == 3) && FeedReg1 == FeedReg2) {
    136                 DEBUG(dbgs()
    137                       << "Optimizing splat/swap or splat/splat "
    138                       "to splat/copy: ");
    139                 DEBUG(MI.dump());
    140                 BuildMI(MBB, &MI, MI.getDebugLoc(),
    141                         TII->get(PPC::COPY), MI.getOperand(0).getReg())
    142                   .addOperand(MI.getOperand(1));
    143                 ToErase = &MI;
    144                 Simplified = true;
    145               }
    146 
    147               // If this is a splat fed by a swap, we can simplify modify
    148               // the splat to splat the other value from the swap's input
    149               // parameter.
    150               else if ((Immed == 0 || Immed == 3)
    151                        && FeedImmed == 2 && FeedReg1 == FeedReg2) {
    152                 DEBUG(dbgs() << "Optimizing swap/splat => splat: ");
    153                 DEBUG(MI.dump());
    154                 MI.getOperand(1).setReg(DefMI->getOperand(1).getReg());
    155                 MI.getOperand(2).setReg(DefMI->getOperand(2).getReg());
    156                 MI.getOperand(3).setImm(3 - Immed);
    157                 Simplified = true;
    158               }
    159 
    160               // If this is a swap fed by a swap, we can replace it
    161               // with a copy from the first swap's input.
    162               else if (Immed == 2 && FeedImmed == 2 && FeedReg1 == FeedReg2) {
    163                 DEBUG(dbgs() << "Optimizing swap/swap => copy: ");
    164                 DEBUG(MI.dump());
    165                 BuildMI(MBB, &MI, MI.getDebugLoc(),
    166                         TII->get(PPC::COPY), MI.getOperand(0).getReg())
    167                   .addOperand(DefMI->getOperand(1));
    168                 ToErase = &MI;
    169                 Simplified = true;
    170               }
    171             }
    172           }
    173         }
    174         break;
    175       }
    176       }
    177     }
    178 
    179     // If the last instruction was marked for elimination,
    180     // remove it now.
    181     if (ToErase) {
    182       ToErase->eraseFromParent();
    183       ToErase = nullptr;
    184     }
    185   }
    186 
    187   return Simplified;
    188 }
    189 
    190 // This is used to find the "true" source register for an
    191 // XXPERMDI instruction, since MachineCSE does not handle the
    192 // "copy-like" operations (Copy and SubregToReg).  Returns
    193 // the original SrcReg unless it is the target of a copy-like
    194 // operation, in which case we chain backwards through all
    195 // such operations to the ultimate source register.  If a
    196 // physical register is encountered, we stop the search.
    197 unsigned PPCMIPeephole::lookThruCopyLike(unsigned SrcReg) {
    198 
    199   while (true) {
    200 
    201     MachineInstr *MI = MRI->getVRegDef(SrcReg);
    202     if (!MI->isCopyLike())
    203       return SrcReg;
    204 
    205     unsigned CopySrcReg;
    206     if (MI->isCopy())
    207       CopySrcReg = MI->getOperand(1).getReg();
    208     else {
    209       assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike");
    210       CopySrcReg = MI->getOperand(2).getReg();
    211     }
    212 
    213     if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg))
    214       return CopySrcReg;
    215 
    216     SrcReg = CopySrcReg;
    217   }
    218 }
    219 
    220 } // end default namespace
    221 
    222 INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE,
    223                       "PowerPC MI Peephole Optimization", false, false)
    224 INITIALIZE_PASS_END(PPCMIPeephole, DEBUG_TYPE,
    225                     "PowerPC MI Peephole Optimization", false, false)
    226 
    227 char PPCMIPeephole::ID = 0;
    228 FunctionPass*
    229 llvm::createPPCMIPeepholePass() { return new PPCMIPeephole(); }
    230 
    231