1*9880d681SAndroid Build Coastguard Worker //===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker // This peephole pass optimizes in the following cases.
9*9880d681SAndroid Build Coastguard Worker // 1. Optimizes redundant sign extends for the following case
10*9880d681SAndroid Build Coastguard Worker // Transform the following pattern
11*9880d681SAndroid Build Coastguard Worker // %vreg170<def> = SXTW %vreg166
12*9880d681SAndroid Build Coastguard Worker // ...
13*9880d681SAndroid Build Coastguard Worker // %vreg176<def> = COPY %vreg170:subreg_loreg
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker // Into
16*9880d681SAndroid Build Coastguard Worker // %vreg176<def> = COPY vreg166
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker // 2. Optimizes redundant negation of predicates.
19*9880d681SAndroid Build Coastguard Worker // %vreg15<def> = CMPGTrr %vreg6, %vreg2
20*9880d681SAndroid Build Coastguard Worker // ...
21*9880d681SAndroid Build Coastguard Worker // %vreg16<def> = NOT_p %vreg15<kill>
22*9880d681SAndroid Build Coastguard Worker // ...
23*9880d681SAndroid Build Coastguard Worker // JMP_c %vreg16<kill>, <BB#1>, %PC<imp-def,dead>
24*9880d681SAndroid Build Coastguard Worker //
25*9880d681SAndroid Build Coastguard Worker // Into
26*9880d681SAndroid Build Coastguard Worker // %vreg15<def> = CMPGTrr %vreg6, %vreg2;
27*9880d681SAndroid Build Coastguard Worker // ...
28*9880d681SAndroid Build Coastguard Worker // JMP_cNot %vreg15<kill>, <BB#1>, %PC<imp-def,dead>;
29*9880d681SAndroid Build Coastguard Worker //
30*9880d681SAndroid Build Coastguard Worker // Note: The peephole pass makes the instrucstions like
31*9880d681SAndroid Build Coastguard Worker // %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill>
32*9880d681SAndroid Build Coastguard Worker // redundant and relies on some form of dead removal instructions, like
33*9880d681SAndroid Build Coastguard Worker // DCE or DIE to actually eliminate them.
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker #include "Hexagon.h"
39*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetMachine.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/PassSupport.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
50*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
52*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
53*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
54*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
55*9880d681SAndroid Build Coastguard Worker #include <algorithm>
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker using namespace llvm;
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "hexagon-peephole"
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
62*9880d681SAndroid Build Coastguard Worker cl::Hidden, cl::ZeroOrMore, cl::init(false),
63*9880d681SAndroid Build Coastguard Worker cl::desc("Disable Peephole Optimization"));
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
66*9880d681SAndroid Build Coastguard Worker cl::Hidden, cl::ZeroOrMore, cl::init(false),
67*9880d681SAndroid Build Coastguard Worker cl::desc("Disable Optimization of PNotP"));
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
70*9880d681SAndroid Build Coastguard Worker cl::Hidden, cl::ZeroOrMore, cl::init(true),
71*9880d681SAndroid Build Coastguard Worker cl::desc("Disable Optimization of Sign/Zero Extends"));
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
74*9880d681SAndroid Build Coastguard Worker cl::Hidden, cl::ZeroOrMore, cl::init(true),
75*9880d681SAndroid Build Coastguard Worker cl::desc("Disable Optimization of extensions to i64."));
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker namespace llvm {
78*9880d681SAndroid Build Coastguard Worker FunctionPass *createHexagonPeephole();
79*9880d681SAndroid Build Coastguard Worker void initializeHexagonPeepholePass(PassRegistry&);
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker namespace {
83*9880d681SAndroid Build Coastguard Worker struct HexagonPeephole : public MachineFunctionPass {
84*9880d681SAndroid Build Coastguard Worker const HexagonInstrInfo *QII;
85*9880d681SAndroid Build Coastguard Worker const HexagonRegisterInfo *QRI;
86*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo *MRI;
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker public:
89*9880d681SAndroid Build Coastguard Worker static char ID;
HexagonPeephole__anon1be751930111::HexagonPeephole90*9880d681SAndroid Build Coastguard Worker HexagonPeephole() : MachineFunctionPass(ID) {
91*9880d681SAndroid Build Coastguard Worker initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
95*9880d681SAndroid Build Coastguard Worker
getPassName__anon1be751930111::HexagonPeephole96*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override {
97*9880d681SAndroid Build Coastguard Worker return "Hexagon optimize redundant zero and size extends";
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage__anon1be751930111::HexagonPeephole100*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
101*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker private:
105*9880d681SAndroid Build Coastguard Worker void ChangeOpInto(MachineOperand &Dst, MachineOperand &Src);
106*9880d681SAndroid Build Coastguard Worker };
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker char HexagonPeephole::ID = 0;
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
112*9880d681SAndroid Build Coastguard Worker false, false)
113*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)114*9880d681SAndroid Build Coastguard Worker bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
115*9880d681SAndroid Build Coastguard Worker if (skipFunction(*MF.getFunction()))
116*9880d681SAndroid Build Coastguard Worker return false;
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
119*9880d681SAndroid Build Coastguard Worker QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
120*9880d681SAndroid Build Coastguard Worker MRI = &MF.getRegInfo();
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker DenseMap<unsigned, unsigned> PeepholeMap;
123*9880d681SAndroid Build Coastguard Worker DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker if (DisableHexagonPeephole) return false;
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker // Loop over all of the basic blocks.
128*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
129*9880d681SAndroid Build Coastguard Worker MBBb != MBBe; ++MBBb) {
130*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = &*MBBb;
131*9880d681SAndroid Build Coastguard Worker PeepholeMap.clear();
132*9880d681SAndroid Build Coastguard Worker PeepholeDoubleRegsMap.clear();
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker // Traverse the basic block.
135*9880d681SAndroid Build Coastguard Worker for (MachineInstr &MI : *MBB) {
136*9880d681SAndroid Build Coastguard Worker // Look for sign extends:
137*9880d681SAndroid Build Coastguard Worker // %vreg170<def> = SXTW %vreg166
138*9880d681SAndroid Build Coastguard Worker if (!DisableOptSZExt && MI.getOpcode() == Hexagon::A2_sxtw) {
139*9880d681SAndroid Build Coastguard Worker assert(MI.getNumOperands() == 2);
140*9880d681SAndroid Build Coastguard Worker MachineOperand &Dst = MI.getOperand(0);
141*9880d681SAndroid Build Coastguard Worker MachineOperand &Src = MI.getOperand(1);
142*9880d681SAndroid Build Coastguard Worker unsigned DstReg = Dst.getReg();
143*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Src.getReg();
144*9880d681SAndroid Build Coastguard Worker // Just handle virtual registers.
145*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
146*9880d681SAndroid Build Coastguard Worker TargetRegisterInfo::isVirtualRegister(SrcReg)) {
147*9880d681SAndroid Build Coastguard Worker // Map the following:
148*9880d681SAndroid Build Coastguard Worker // %vreg170<def> = SXTW %vreg166
149*9880d681SAndroid Build Coastguard Worker // PeepholeMap[170] = vreg166
150*9880d681SAndroid Build Coastguard Worker PeepholeMap[DstReg] = SrcReg;
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker }
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker // Look for %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
155*9880d681SAndroid Build Coastguard Worker // %vreg170:DoublRegs, %vreg169:IntRegs
156*9880d681SAndroid Build Coastguard Worker if (!DisableOptExtTo64 && MI.getOpcode() == Hexagon::A4_combineir) {
157*9880d681SAndroid Build Coastguard Worker assert(MI.getNumOperands() == 3);
158*9880d681SAndroid Build Coastguard Worker MachineOperand &Dst = MI.getOperand(0);
159*9880d681SAndroid Build Coastguard Worker MachineOperand &Src1 = MI.getOperand(1);
160*9880d681SAndroid Build Coastguard Worker MachineOperand &Src2 = MI.getOperand(2);
161*9880d681SAndroid Build Coastguard Worker if (Src1.getImm() != 0)
162*9880d681SAndroid Build Coastguard Worker continue;
163*9880d681SAndroid Build Coastguard Worker unsigned DstReg = Dst.getReg();
164*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Src2.getReg();
165*9880d681SAndroid Build Coastguard Worker PeepholeMap[DstReg] = SrcReg;
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker // Look for this sequence below
169*9880d681SAndroid Build Coastguard Worker // %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
170*9880d681SAndroid Build Coastguard Worker // %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
171*9880d681SAndroid Build Coastguard Worker // and convert into
172*9880d681SAndroid Build Coastguard Worker // %vregIntReg = COPY %vregDoubleReg0:subreg_hireg.
173*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == Hexagon::S2_lsr_i_p) {
174*9880d681SAndroid Build Coastguard Worker assert(MI.getNumOperands() == 3);
175*9880d681SAndroid Build Coastguard Worker MachineOperand &Dst = MI.getOperand(0);
176*9880d681SAndroid Build Coastguard Worker MachineOperand &Src1 = MI.getOperand(1);
177*9880d681SAndroid Build Coastguard Worker MachineOperand &Src2 = MI.getOperand(2);
178*9880d681SAndroid Build Coastguard Worker if (Src2.getImm() != 32)
179*9880d681SAndroid Build Coastguard Worker continue;
180*9880d681SAndroid Build Coastguard Worker unsigned DstReg = Dst.getReg();
181*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Src1.getReg();
182*9880d681SAndroid Build Coastguard Worker PeepholeDoubleRegsMap[DstReg] =
183*9880d681SAndroid Build Coastguard Worker std::make_pair(*&SrcReg, Hexagon::subreg_hireg);
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker // Look for P=NOT(P).
187*9880d681SAndroid Build Coastguard Worker if (!DisablePNotP && MI.getOpcode() == Hexagon::C2_not) {
188*9880d681SAndroid Build Coastguard Worker assert(MI.getNumOperands() == 2);
189*9880d681SAndroid Build Coastguard Worker MachineOperand &Dst = MI.getOperand(0);
190*9880d681SAndroid Build Coastguard Worker MachineOperand &Src = MI.getOperand(1);
191*9880d681SAndroid Build Coastguard Worker unsigned DstReg = Dst.getReg();
192*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Src.getReg();
193*9880d681SAndroid Build Coastguard Worker // Just handle virtual registers.
194*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
195*9880d681SAndroid Build Coastguard Worker TargetRegisterInfo::isVirtualRegister(SrcReg)) {
196*9880d681SAndroid Build Coastguard Worker // Map the following:
197*9880d681SAndroid Build Coastguard Worker // %vreg170<def> = NOT_xx %vreg166
198*9880d681SAndroid Build Coastguard Worker // PeepholeMap[170] = vreg166
199*9880d681SAndroid Build Coastguard Worker PeepholeMap[DstReg] = SrcReg;
200*9880d681SAndroid Build Coastguard Worker }
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker // Look for copy:
204*9880d681SAndroid Build Coastguard Worker // %vreg176<def> = COPY %vreg170:subreg_loreg
205*9880d681SAndroid Build Coastguard Worker if (!DisableOptSZExt && MI.isCopy()) {
206*9880d681SAndroid Build Coastguard Worker assert(MI.getNumOperands() == 2);
207*9880d681SAndroid Build Coastguard Worker MachineOperand &Dst = MI.getOperand(0);
208*9880d681SAndroid Build Coastguard Worker MachineOperand &Src = MI.getOperand(1);
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker // Make sure we are copying the lower 32 bits.
211*9880d681SAndroid Build Coastguard Worker if (Src.getSubReg() != Hexagon::subreg_loreg)
212*9880d681SAndroid Build Coastguard Worker continue;
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker unsigned DstReg = Dst.getReg();
215*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Src.getReg();
216*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
217*9880d681SAndroid Build Coastguard Worker TargetRegisterInfo::isVirtualRegister(SrcReg)) {
218*9880d681SAndroid Build Coastguard Worker // Try to find in the map.
219*9880d681SAndroid Build Coastguard Worker if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
220*9880d681SAndroid Build Coastguard Worker // Change the 1st operand.
221*9880d681SAndroid Build Coastguard Worker MI.RemoveOperand(1);
222*9880d681SAndroid Build Coastguard Worker MI.addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
223*9880d681SAndroid Build Coastguard Worker } else {
224*9880d681SAndroid Build Coastguard Worker DenseMap<unsigned, std::pair<unsigned, unsigned> >::iterator DI =
225*9880d681SAndroid Build Coastguard Worker PeepholeDoubleRegsMap.find(SrcReg);
226*9880d681SAndroid Build Coastguard Worker if (DI != PeepholeDoubleRegsMap.end()) {
227*9880d681SAndroid Build Coastguard Worker std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
228*9880d681SAndroid Build Coastguard Worker MI.RemoveOperand(1);
229*9880d681SAndroid Build Coastguard Worker MI.addOperand(MachineOperand::CreateReg(
230*9880d681SAndroid Build Coastguard Worker PeepholeSrc.first, false /*isDef*/, false /*isImp*/,
231*9880d681SAndroid Build Coastguard Worker false /*isKill*/, false /*isDead*/, false /*isUndef*/,
232*9880d681SAndroid Build Coastguard Worker false /*isEarlyClobber*/, PeepholeSrc.second));
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker }
236*9880d681SAndroid Build Coastguard Worker }
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker // Look for Predicated instructions.
239*9880d681SAndroid Build Coastguard Worker if (!DisablePNotP) {
240*9880d681SAndroid Build Coastguard Worker bool Done = false;
241*9880d681SAndroid Build Coastguard Worker if (QII->isPredicated(MI)) {
242*9880d681SAndroid Build Coastguard Worker MachineOperand &Op0 = MI.getOperand(0);
243*9880d681SAndroid Build Coastguard Worker unsigned Reg0 = Op0.getReg();
244*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
245*9880d681SAndroid Build Coastguard Worker if (RC0->getID() == Hexagon::PredRegsRegClassID) {
246*9880d681SAndroid Build Coastguard Worker // Handle instructions that have a prediate register in op0
247*9880d681SAndroid Build Coastguard Worker // (most cases of predicable instructions).
248*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isVirtualRegister(Reg0)) {
249*9880d681SAndroid Build Coastguard Worker // Try to find in the map.
250*9880d681SAndroid Build Coastguard Worker if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
251*9880d681SAndroid Build Coastguard Worker // Change the 1st operand and, flip the opcode.
252*9880d681SAndroid Build Coastguard Worker MI.getOperand(0).setReg(PeepholeSrc);
253*9880d681SAndroid Build Coastguard Worker int NewOp = QII->getInvertedPredicatedOpcode(MI.getOpcode());
254*9880d681SAndroid Build Coastguard Worker MI.setDesc(QII->get(NewOp));
255*9880d681SAndroid Build Coastguard Worker Done = true;
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker if (!Done) {
262*9880d681SAndroid Build Coastguard Worker // Handle special instructions.
263*9880d681SAndroid Build Coastguard Worker unsigned Op = MI.getOpcode();
264*9880d681SAndroid Build Coastguard Worker unsigned NewOp = 0;
265*9880d681SAndroid Build Coastguard Worker unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices.
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker switch (Op) {
268*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_mux:
269*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_muxii:
270*9880d681SAndroid Build Coastguard Worker NewOp = Op;
271*9880d681SAndroid Build Coastguard Worker break;
272*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_muxri:
273*9880d681SAndroid Build Coastguard Worker NewOp = Hexagon::C2_muxir;
274*9880d681SAndroid Build Coastguard Worker break;
275*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_muxir:
276*9880d681SAndroid Build Coastguard Worker NewOp = Hexagon::C2_muxri;
277*9880d681SAndroid Build Coastguard Worker break;
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker if (NewOp) {
280*9880d681SAndroid Build Coastguard Worker unsigned PSrc = MI.getOperand(PR).getReg();
281*9880d681SAndroid Build Coastguard Worker if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
282*9880d681SAndroid Build Coastguard Worker MI.getOperand(PR).setReg(POrig);
283*9880d681SAndroid Build Coastguard Worker MI.setDesc(QII->get(NewOp));
284*9880d681SAndroid Build Coastguard Worker // Swap operands S1 and S2.
285*9880d681SAndroid Build Coastguard Worker MachineOperand Op1 = MI.getOperand(S1);
286*9880d681SAndroid Build Coastguard Worker MachineOperand Op2 = MI.getOperand(S2);
287*9880d681SAndroid Build Coastguard Worker ChangeOpInto(MI.getOperand(S1), Op2);
288*9880d681SAndroid Build Coastguard Worker ChangeOpInto(MI.getOperand(S2), Op1);
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker } // if (NewOp)
291*9880d681SAndroid Build Coastguard Worker } // if (!Done)
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker } // if (!DisablePNotP)
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker } // Instruction
296*9880d681SAndroid Build Coastguard Worker } // Basic Block
297*9880d681SAndroid Build Coastguard Worker return true;
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker
ChangeOpInto(MachineOperand & Dst,MachineOperand & Src)300*9880d681SAndroid Build Coastguard Worker void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) {
301*9880d681SAndroid Build Coastguard Worker assert (&Dst != &Src && "Cannot duplicate into itself");
302*9880d681SAndroid Build Coastguard Worker switch (Dst.getType()) {
303*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Register:
304*9880d681SAndroid Build Coastguard Worker if (Src.isReg()) {
305*9880d681SAndroid Build Coastguard Worker Dst.setReg(Src.getReg());
306*9880d681SAndroid Build Coastguard Worker Dst.setSubReg(Src.getSubReg());
307*9880d681SAndroid Build Coastguard Worker } else if (Src.isImm()) {
308*9880d681SAndroid Build Coastguard Worker Dst.ChangeToImmediate(Src.getImm());
309*9880d681SAndroid Build Coastguard Worker } else {
310*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected src operand type");
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker break;
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker case MachineOperand::MO_Immediate:
315*9880d681SAndroid Build Coastguard Worker if (Src.isImm()) {
316*9880d681SAndroid Build Coastguard Worker Dst.setImm(Src.getImm());
317*9880d681SAndroid Build Coastguard Worker } else if (Src.isReg()) {
318*9880d681SAndroid Build Coastguard Worker Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(),
319*9880d681SAndroid Build Coastguard Worker Src.isKill(), Src.isDead(), Src.isUndef(),
320*9880d681SAndroid Build Coastguard Worker Src.isDebug());
321*9880d681SAndroid Build Coastguard Worker Dst.setSubReg(Src.getSubReg());
322*9880d681SAndroid Build Coastguard Worker } else {
323*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected src operand type");
324*9880d681SAndroid Build Coastguard Worker }
325*9880d681SAndroid Build Coastguard Worker break;
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker default:
328*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected dst operand type");
329*9880d681SAndroid Build Coastguard Worker break;
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker
createHexagonPeephole()333*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createHexagonPeephole() {
334*9880d681SAndroid Build Coastguard Worker return new HexagonPeephole();
335*9880d681SAndroid Build Coastguard Worker }
336