LLVM API Documentation
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 }