xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonPeephole.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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