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 || DefInsn->isPHI()) 80 return false; 81 82 if (DefInsn->getOpcode() == BPF::COPY) { 83 MachineOperand &opnd = DefInsn->getOperand(1); 84 85 if (!opnd.isReg()) 86 return false; 87 88 unsigned Reg = opnd.getReg(); 89 if ((TargetRegisterInfo::isVirtualRegister(Reg) && 90 MRI->getRegClass(Reg) == &BPF::GPRRegClass)) 91 return false; 92 } 93 94 return true; 95 } 96 97 bool BPFMIPeephole::eliminateZExtSeq(void) { 98 MachineInstr* ToErase = nullptr; 99 bool Eliminated = false; 100 101 for (MachineBasicBlock &MBB : *MF) { 102 for (MachineInstr &MI : MBB) { 103 // If the previous instruction was marked for elimination, remove it now. 104 if (ToErase) { 105 ToErase->eraseFromParent(); 106 ToErase = nullptr; 107 } 108 109 // Eliminate the 32-bit to 64-bit zero extension sequence when possible. 110 // 111 // MOV_32_64 rB, wA 112 // SLL_ri rB, rB, 32 113 // SRL_ri rB, rB, 32 114 if (MI.getOpcode() == BPF::SRL_ri && 115 MI.getOperand(2).getImm() == 32) { 116 unsigned DstReg = MI.getOperand(0).getReg(); 117 unsigned ShfReg = MI.getOperand(1).getReg(); 118 MachineInstr *SllMI = MRI->getVRegDef(ShfReg); 119 120 if (!SllMI || 121 SllMI->isPHI() || 122 SllMI->getOpcode() != BPF::SLL_ri || 123 SllMI->getOperand(2).getImm() != 32) 124 continue; 125 126 MachineInstr *MovMI = MRI->getVRegDef(SllMI->getOperand(1).getReg()); 127 if (!MovMI || 128 MovMI->isPHI() || 129 MovMI->getOpcode() != BPF::MOV_32_64) 130 continue; 131 132 if (!isMovFrom32Def(MovMI)) 133 continue; 134 135 unsigned SubReg = MovMI->getOperand(1).getReg(); 136 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(BPF::SUBREG_TO_REG), DstReg) 137 .addImm(0).addReg(SubReg).addImm(BPF::sub_32); 138 139 SllMI->eraseFromParent(); 140 MovMI->eraseFromParent(); 141 // MI is the right shift, we can't erase it in it's own iteration. 142 // Mark it to ToErase, and erase in the next iteration. 143 ToErase = &MI; 144 ZExtElemNum++; 145 Eliminated = true; 146 } 147 } 148 } 149 150 return Eliminated; 151 } 152 153 } // end default namespace 154 155 INITIALIZE_PASS(BPFMIPeephole, DEBUG_TYPE, "BPF MI Peephole Optimization", 156 false, false) 157 158 char BPFMIPeephole::ID = 0; 159 FunctionPass* llvm::createBPFMIPeepholePass() { return new BPFMIPeephole(); } 160