blob: b15a7e6663e632a75a6d1575ba45d7adb05c0089 [file] [log] [blame]
Yonghong Song60fed1f2018-02-23 23:49:32 +00001//===-------------- 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
28using namespace llvm;
29
Yonghong Songc88bcde2018-03-13 06:47:03 +000030#define DEBUG_TYPE "bpf-mi-zext-elim"
Yonghong Song60fed1f2018-02-23 23:49:32 +000031
Yonghong Songc88bcde2018-03-13 06:47:03 +000032STATISTIC(ZExtElemNum, "Number of zero extension shifts eliminated");
Yonghong Song60fed1f2018-02-23 23:49:32 +000033
34namespace {
35
36struct 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
47private:
48 // Initialize class variables.
49 void initialize(MachineFunction &MFParm);
50
Yonghong Songc88bcde2018-03-13 06:47:03 +000051 bool isMovFrom32Def(MachineInstr *MovMI);
52 bool eliminateZExtSeq(void);
Yonghong Song60fed1f2018-02-23 23:49:32 +000053
54public:
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
Yonghong Songc88bcde2018-03-13 06:47:03 +000063 return eliminateZExtSeq();
Yonghong Song60fed1f2018-02-23 23:49:32 +000064 }
65};
66
67// Initialize class variables.
68void 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
Yonghong Songc88bcde2018-03-13 06:47:03 +000075bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI)
76{
77 MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg());
Yonghong Song60fed1f2018-02-23 23:49:32 +000078
Yonghong Songc88bcde2018-03-13 06:47:03 +000079 if (!DefInsn || DefInsn->isPHI())
80 return false;
Yonghong Song60fed1f2018-02-23 23:49:32 +000081
Yonghong Songc88bcde2018-03-13 06:47:03 +000082 if (DefInsn->getOpcode() == BPF::COPY) {
83 MachineOperand &opnd = DefInsn->getOperand(1);
Yonghong Song89e47ac2018-03-13 06:47:00 +000084
85 if (!opnd.isReg())
Yonghong Songc88bcde2018-03-13 06:47:03 +000086 return false;
Yonghong Song89e47ac2018-03-13 06:47:00 +000087
88 unsigned Reg = opnd.getReg();
89 if ((TargetRegisterInfo::isVirtualRegister(Reg) &&
Yonghong Songc88bcde2018-03-13 06:47:03 +000090 MRI->getRegClass(Reg) == &BPF::GPRRegClass))
91 return false;
Yonghong Song89e47ac2018-03-13 06:47:00 +000092 }
93
Yonghong Songc88bcde2018-03-13 06:47:03 +000094 return true;
Yonghong Song60fed1f2018-02-23 23:49:32 +000095}
96
Yonghong Songc88bcde2018-03-13 06:47:03 +000097bool BPFMIPeephole::eliminateZExtSeq(void) {
98 MachineInstr* ToErase = nullptr;
Yonghong Song60fed1f2018-02-23 23:49:32 +000099 bool Eliminated = false;
Yonghong Song60fed1f2018-02-23 23:49:32 +0000100
101 for (MachineBasicBlock &MBB : *MF) {
102 for (MachineInstr &MI : MBB) {
Yonghong Songc88bcde2018-03-13 06:47:03 +0000103 // If the previous instruction was marked for elimination, remove it now.
104 if (ToErase) {
105 ToErase->eraseFromParent();
106 ToErase = nullptr;
107 }
Yonghong Song60fed1f2018-02-23 23:49:32 +0000108
Yonghong Songc88bcde2018-03-13 06:47:03 +0000109 // 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;
Yonghong Song60fed1f2018-02-23 23:49:32 +0000146 }
147 }
148 }
149
150 return Eliminated;
151}
152
153} // end default namespace
154
155INITIALIZE_PASS(BPFMIPeephole, DEBUG_TYPE, "BPF MI Peephole Optimization",
156 false, false)
157
158char BPFMIPeephole::ID = 0;
159FunctionPass* llvm::createBPFMIPeepholePass() { return new BPFMIPeephole(); }