LLVM API Documentation

HexagonPeephole.cpp
Go to the documentation of this file.
00001 //===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 // This peephole pass optimizes in the following cases.
00009 // 1. Optimizes redundant sign extends for the following case
00010 //    Transform the following pattern
00011 //    %vreg170<def> = SXTW %vreg166
00012 //    ...
00013 //    %vreg176<def> = COPY %vreg170:subreg_loreg
00014 //
00015 //    Into
00016 //    %vreg176<def> = COPY vreg166
00017 //
00018 //  2. Optimizes redundant negation of predicates.
00019 //     %vreg15<def> = CMPGTrr %vreg6, %vreg2
00020 //     ...
00021 //     %vreg16<def> = NOT_p %vreg15<kill>
00022 //     ...
00023 //     JMP_c %vreg16<kill>, <BB#1>, %PC<imp-def,dead>
00024 //
00025 //     Into
00026 //     %vreg15<def> = CMPGTrr %vreg6, %vreg2;
00027 //     ...
00028 //     JMP_cNot %vreg15<kill>, <BB#1>, %PC<imp-def,dead>;
00029 //
00030 // Note: The peephole pass makes the instrucstions like
00031 // %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill>
00032 // redundant and relies on some form of dead removal instructions, like
00033 // DCE or DIE to actually eliminate them.
00034 
00035 
00036 //===----------------------------------------------------------------------===//
00037 
00038 #include "Hexagon.h"
00039 #include "HexagonTargetMachine.h"
00040 #include "llvm/ADT/DenseMap.h"
00041 #include "llvm/ADT/Statistic.h"
00042 #include "llvm/CodeGen/MachineFunction.h"
00043 #include "llvm/CodeGen/MachineFunctionPass.h"
00044 #include "llvm/CodeGen/MachineInstrBuilder.h"
00045 #include "llvm/CodeGen/MachineRegisterInfo.h"
00046 #include "llvm/CodeGen/Passes.h"
00047 #include "llvm/IR/Constants.h"
00048 #include "llvm/PassSupport.h"
00049 #include "llvm/Support/CommandLine.h"
00050 #include "llvm/Support/Debug.h"
00051 #include "llvm/Support/raw_ostream.h"
00052 #include "llvm/Target/TargetInstrInfo.h"
00053 #include "llvm/Target/TargetMachine.h"
00054 #include "llvm/Target/TargetRegisterInfo.h"
00055 #include <algorithm>
00056 
00057 using namespace llvm;
00058 
00059 #define DEBUG_TYPE "hexagon-peephole"
00060 
00061 static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
00062     cl::Hidden, cl::ZeroOrMore, cl::init(false),
00063     cl::desc("Disable Peephole Optimization"));
00064 
00065 static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
00066     cl::Hidden, cl::ZeroOrMore, cl::init(false),
00067     cl::desc("Disable Optimization of PNotP"));
00068 
00069 static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
00070     cl::Hidden, cl::ZeroOrMore, cl::init(false),
00071     cl::desc("Disable Optimization of Sign/Zero Extends"));
00072 
00073 static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
00074     cl::Hidden, cl::ZeroOrMore, cl::init(false),
00075     cl::desc("Disable Optimization of extensions to i64."));
00076 
00077 namespace llvm {
00078   void initializeHexagonPeepholePass(PassRegistry&);
00079 }
00080 
00081 namespace {
00082   struct HexagonPeephole : public MachineFunctionPass {
00083     const HexagonInstrInfo    *QII;
00084     const HexagonRegisterInfo *QRI;
00085     const MachineRegisterInfo *MRI;
00086 
00087   public:
00088     static char ID;
00089     HexagonPeephole() : MachineFunctionPass(ID) {
00090       initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
00091     }
00092 
00093     bool runOnMachineFunction(MachineFunction &MF) override;
00094 
00095     const char *getPassName() const override {
00096       return "Hexagon optimize redundant zero and size extends";
00097     }
00098 
00099     void getAnalysisUsage(AnalysisUsage &AU) const override {
00100       MachineFunctionPass::getAnalysisUsage(AU);
00101     }
00102 
00103   private:
00104     void ChangeOpInto(MachineOperand &Dst, MachineOperand &Src);
00105   };
00106 }
00107 
00108 char HexagonPeephole::ID = 0;
00109 
00110 INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
00111                 false, false)
00112 
00113 bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
00114   QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
00115   QRI = MF.getTarget().getSubtarget<HexagonSubtarget>().getRegisterInfo();
00116   MRI = &MF.getRegInfo();
00117 
00118   DenseMap<unsigned, unsigned> PeepholeMap;
00119   DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
00120 
00121   if (DisableHexagonPeephole) return false;
00122 
00123   // Loop over all of the basic blocks.
00124   for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
00125        MBBb != MBBe; ++MBBb) {
00126     MachineBasicBlock* MBB = MBBb;
00127     PeepholeMap.clear();
00128     PeepholeDoubleRegsMap.clear();
00129 
00130     // Traverse the basic block.
00131     for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
00132                                      ++MII) {
00133       MachineInstr *MI = MII;
00134       // Look for sign extends:
00135       // %vreg170<def> = SXTW %vreg166
00136       if (!DisableOptSZExt && MI->getOpcode() == Hexagon::SXTW) {
00137         assert (MI->getNumOperands() == 2);
00138         MachineOperand &Dst = MI->getOperand(0);
00139         MachineOperand &Src  = MI->getOperand(1);
00140         unsigned DstReg = Dst.getReg();
00141         unsigned SrcReg = Src.getReg();
00142         // Just handle virtual registers.
00143         if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
00144             TargetRegisterInfo::isVirtualRegister(SrcReg)) {
00145           // Map the following:
00146           // %vreg170<def> = SXTW %vreg166
00147           // PeepholeMap[170] = vreg166
00148           PeepholeMap[DstReg] = SrcReg;
00149         }
00150       }
00151 
00152       // Look for  %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
00153       // %vreg170:DoublRegs, %vreg169:IntRegs
00154       if (!DisableOptExtTo64 &&
00155           MI->getOpcode () == Hexagon::COMBINE_Ir_V4) {
00156         assert (MI->getNumOperands() == 3);
00157         MachineOperand &Dst = MI->getOperand(0);
00158         MachineOperand &Src1 = MI->getOperand(1);
00159         MachineOperand &Src2 = MI->getOperand(2);
00160         if (Src1.getImm() != 0)
00161           continue;
00162         unsigned DstReg = Dst.getReg();
00163         unsigned SrcReg = Src2.getReg();
00164         PeepholeMap[DstReg] = SrcReg;
00165       }
00166 
00167       // Look for this sequence below
00168       // %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
00169       // %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
00170       // and convert into
00171       // %vregIntReg = COPY %vregDoubleReg0:subreg_hireg.
00172       if (MI->getOpcode() == Hexagon::LSRd_ri) {
00173         assert(MI->getNumOperands() == 3);
00174         MachineOperand &Dst = MI->getOperand(0);
00175         MachineOperand &Src1 = MI->getOperand(1);
00176         MachineOperand &Src2 = MI->getOperand(2);
00177         if (Src2.getImm() != 32)
00178           continue;
00179         unsigned DstReg = Dst.getReg();
00180         unsigned SrcReg = Src1.getReg();
00181         PeepholeDoubleRegsMap[DstReg] =
00182           std::make_pair(*&SrcReg, 1/*Hexagon::subreg_hireg*/);
00183       }
00184 
00185       // Look for P=NOT(P).
00186       if (!DisablePNotP &&
00187           (MI->getOpcode() == Hexagon::NOT_p)) {
00188         assert (MI->getNumOperands() == 2);
00189         MachineOperand &Dst = MI->getOperand(0);
00190         MachineOperand &Src  = MI->getOperand(1);
00191         unsigned DstReg = Dst.getReg();
00192         unsigned SrcReg = Src.getReg();
00193         // Just handle virtual registers.
00194         if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
00195             TargetRegisterInfo::isVirtualRegister(SrcReg)) {
00196           // Map the following:
00197           // %vreg170<def> = NOT_xx %vreg166
00198           // PeepholeMap[170] = vreg166
00199           PeepholeMap[DstReg] = SrcReg;
00200         }
00201       }
00202 
00203       // Look for copy:
00204       // %vreg176<def> = COPY %vreg170:subreg_loreg
00205       if (!DisableOptSZExt && MI->isCopy()) {
00206         assert (MI->getNumOperands() == 2);
00207         MachineOperand &Dst = MI->getOperand(0);
00208         MachineOperand &Src  = MI->getOperand(1);
00209 
00210         // Make sure we are copying the lower 32 bits.
00211         if (Src.getSubReg() != Hexagon::subreg_loreg)
00212           continue;
00213 
00214         unsigned DstReg = Dst.getReg();
00215         unsigned SrcReg = Src.getReg();
00216         if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
00217             TargetRegisterInfo::isVirtualRegister(SrcReg)) {
00218           // Try to find in the map.
00219           if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
00220             // Change the 1st operand.
00221             MI->RemoveOperand(1);
00222             MI->addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
00223           } else  {
00224             DenseMap<unsigned, std::pair<unsigned, unsigned> >::iterator DI =
00225               PeepholeDoubleRegsMap.find(SrcReg);
00226             if (DI != PeepholeDoubleRegsMap.end()) {
00227               std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
00228               MI->RemoveOperand(1);
00229               MI->addOperand(MachineOperand::CreateReg(PeepholeSrc.first,
00230                                                        false /*isDef*/,
00231                                                        false /*isImp*/,
00232                                                        false /*isKill*/,
00233                                                        false /*isDead*/,
00234                                                        false /*isUndef*/,
00235                                                        false /*isEarlyClobber*/,
00236                                                        PeepholeSrc.second));
00237             }
00238           }
00239         }
00240       }
00241 
00242       // Look for Predicated instructions.
00243       if (!DisablePNotP) {
00244         bool Done = false;
00245         if (QII->isPredicated(MI)) {
00246           MachineOperand &Op0 = MI->getOperand(0);
00247           unsigned Reg0 = Op0.getReg();
00248           const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
00249           if (RC0->getID() == Hexagon::PredRegsRegClassID) {
00250             // Handle instructions that have a prediate register in op0
00251             // (most cases of predicable instructions).
00252             if (TargetRegisterInfo::isVirtualRegister(Reg0)) {
00253               // Try to find in the map.
00254               if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
00255                 // Change the 1st operand and, flip the opcode.
00256                 MI->getOperand(0).setReg(PeepholeSrc);
00257                 int NewOp = QII->getInvertedPredicatedOpcode(MI->getOpcode());
00258                 MI->setDesc(QII->get(NewOp));
00259                 Done = true;
00260               }
00261             }
00262           }
00263         }
00264 
00265         if (!Done) {
00266           // Handle special instructions.
00267           unsigned Op = MI->getOpcode();
00268           unsigned NewOp = 0;
00269           unsigned PR = 1, S1 = 2, S2 = 3;   // Operand indices.
00270 
00271           switch (Op) {
00272             case Hexagon::TFR_condset_rr:
00273             case Hexagon::TFR_condset_ii:
00274             case Hexagon::MUX_ii:
00275             case Hexagon::MUX_rr:
00276               NewOp = Op;
00277               break;
00278             case Hexagon::TFR_condset_ri:
00279               NewOp = Hexagon::TFR_condset_ir;
00280               break;
00281             case Hexagon::TFR_condset_ir:
00282               NewOp = Hexagon::TFR_condset_ri;
00283               break;
00284             case Hexagon::MUX_ri:
00285               NewOp = Hexagon::MUX_ir;
00286               break;
00287             case Hexagon::MUX_ir:
00288               NewOp = Hexagon::MUX_ri;
00289               break;
00290           }
00291           if (NewOp) {
00292             unsigned PSrc = MI->getOperand(PR).getReg();
00293             if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
00294               MI->getOperand(PR).setReg(POrig);
00295               MI->setDesc(QII->get(NewOp));
00296               // Swap operands S1 and S2.
00297               MachineOperand Op1 = MI->getOperand(S1);
00298               MachineOperand Op2 = MI->getOperand(S2);
00299               ChangeOpInto(MI->getOperand(S1), Op2);
00300               ChangeOpInto(MI->getOperand(S2), Op1);
00301             }
00302           } // if (NewOp)
00303         } // if (!Done)
00304 
00305       } // if (!DisablePNotP)
00306 
00307     } // Instruction
00308   } // Basic Block
00309   return true;
00310 }
00311 
00312 void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) {
00313   assert (&Dst != &Src && "Cannot duplicate into itself");
00314   switch (Dst.getType()) {
00315     case MachineOperand::MO_Register:
00316       if (Src.isReg()) {
00317         Dst.setReg(Src.getReg());
00318       } else if (Src.isImm()) {
00319         Dst.ChangeToImmediate(Src.getImm());
00320       } else {
00321         llvm_unreachable("Unexpected src operand type");
00322       }
00323       break;
00324 
00325     case MachineOperand::MO_Immediate:
00326       if (Src.isImm()) {
00327         Dst.setImm(Src.getImm());
00328       } else if (Src.isReg()) {
00329         Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(),
00330                              Src.isKill(), Src.isDead(), Src.isUndef(),
00331                              Src.isDebug());
00332       } else {
00333         llvm_unreachable("Unexpected src operand type");
00334       }
00335       break;
00336 
00337     default:
00338       llvm_unreachable("Unexpected dst operand type");
00339       break;
00340   }
00341 }
00342 
00343 FunctionPass *llvm::createHexagonPeephole() {
00344   return new HexagonPeephole();
00345 }