1 //===-------------- BPFMIPeephole.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 cleanup ugly code sequences at 11 // MachineInstruction layer. 12 // 13 // Currently, the only optimization in this pass is to eliminate type promotion 14 // sequences, those zero extend 32-bit subregisters to 64-bit registers, if the 15 // compiler could prove the subregisters is defined by 32-bit operations in 16 // which case the upper half of the underlying 64-bit registers were zeroed 17 // implicitly. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #include "BPF.h" 22 #include "BPFInstrInfo.h" 23 #include "BPFTargetMachine.h" 24 #include "llvm/ADT/Statistic.h" 25 #include "llvm/CodeGen/MachineInstrBuilder.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 28 using namespace llvm; 29 30 #define DEBUG_TYPE "bpf-mi-zext-elim" 31 32 STATISTIC(ZExtElemNum, "Number of zero extension shifts eliminated"); 33 34 namespace { 35 36 struct BPFMIPeephole : public MachineFunctionPass { 37 38 static char ID; 39 const BPFInstrInfo *TII; 40 MachineFunction *MF; 41 MachineRegisterInfo *MRI; 42 43 BPFMIPeephole() : MachineFunctionPass(ID) { 44 initializeBPFMIPeepholePass(*PassRegistry::getPassRegistry()); 45 } 46 47 private: 48 // Initialize class variables. 49 void initialize(MachineFunction &MFParm); 50 51 bool isMovFrom32Def(MachineInstr *MovMI); 52 bool eliminateZExtSeq(void); 53 54 public: 55 56 // Main entry point for this pass. 57 bool runOnMachineFunction(MachineFunction &MF) override { 58 if (skipFunction(MF.getFunction())) 59 return false; 60 61 initialize(MF); 62 63 return eliminateZExtSeq(); 64 } 65 }; 66 67 // Initialize class variables. 68 void BPFMIPeephole::initialize(MachineFunction &MFParm) { 69 MF = &MFParm; 70 MRI = &MF->getRegInfo(); 71 TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo(); 72 DEBUG(dbgs() << "*** BPF MI peephole pass ***\n\n"); 73 } 74 75 bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI) 76 { 77 MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg()); 78 79 if (!DefInsn) 80 return false; 81 82 if (DefInsn->isPHI()) { 83 for (unsigned i = 1, e = DefInsn->getNumOperands(); i < e; i += 2) { 84 MachineOperand &opnd = DefInsn->getOperand(i); 85 86 if (!opnd.isReg()) 87 return false; 88 89 MachineInstr *PhiDef = MRI->getVRegDef(opnd.getReg()); 90 // quick check on PHI incoming definitions. 91 if (!PhiDef || PhiDef->isPHI() || PhiDef->getOpcode() == BPF::COPY) 92 return false; 93 } 94 } 95 96 if (DefInsn->getOpcode() == BPF::COPY) { 97 MachineOperand &opnd = DefInsn->getOperand(1); 98 99 if (!opnd.isReg()) 100 return false; 101 102 unsigned Reg = opnd.getReg(); 103 if ((TargetRegisterInfo::isVirtualRegister(Reg) && 104 MRI->getRegClass(Reg) == &BPF::GPRRegClass)) 105 return false; 106 } 107 108 return true; 109 } 110 111 bool BPFMIPeephole::eliminateZExtSeq(void) { 112 MachineInstr* ToErase = nullptr; 113 bool Eliminated = false; 114 115 for (MachineBasicBlock &MBB : *MF) { 116 for (MachineInstr &MI : MBB) { 117 // If the previous instruction was marked for elimination, remove it now. 118 if (ToErase) { 119 ToErase->eraseFromParent(); 120 ToErase = nullptr; 121 } 122 123 // Eliminate the 32-bit to 64-bit zero extension sequence when possible. 124 // 125 // MOV_32_64 rB, wA 126 // SLL_ri rB, rB, 32 127 // SRL_ri rB, rB, 32 128 if (MI.getOpcode() == BPF::SRL_ri && 129 MI.getOperand(2).getImm() == 32) { 130 unsigned DstReg = MI.getOperand(0).getReg(); 131 unsigned ShfReg = MI.getOperand(1).getReg(); 132 MachineInstr *SllMI = MRI->getVRegDef(ShfReg); 133 134 if (!SllMI || 135 SllMI->isPHI() || 136 SllMI->getOpcode() != BPF::SLL_ri || 137 SllMI->getOperand(2).getImm() != 32) 138 continue; 139 140 MachineInstr *MovMI = MRI->getVRegDef(SllMI->getOperand(1).getReg()); 141 if (!MovMI || 142 MovMI->isPHI() || 143 MovMI->getOpcode() != BPF::MOV_32_64) 144 continue; 145 146 unsigned SubReg = MovMI->getOperand(1).getReg(); 147 if (!isMovFrom32Def(MovMI)) 148 continue; 149 150 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(BPF::SUBREG_TO_REG), DstReg) 151 .addImm(0).addReg(SubReg).addImm(BPF::sub_32); 152 153 SllMI->eraseFromParent(); 154 MovMI->eraseFromParent(); 155 // MI is the right shift, we can't erase it in it's own iteration. 156 // Mark it to ToErase, and erase in the next iteration. 157 ToErase = &MI; 158 ZExtElemNum++; 159 Eliminated = true; 160 } 161 } 162 } 163 164 return Eliminated; 165 } 166 167 } // end default namespace 168 169 INITIALIZE_PASS(BPFMIPeephole, DEBUG_TYPE, "BPF MI Peephole Optimization", 170 false, false) 171 172 char BPFMIPeephole::ID = 0; 173 FunctionPass* llvm::createBPFMIPeepholePass() { return new BPFMIPeephole(); } 174