1ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
2ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
3ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//                     The LLVM Compiler Infrastructure
4ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
5ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// This file is distributed under the University of Illinois Open Source
6ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// License. See LICENSE.TXT for details.
7ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
8ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// This peephole pass optimizes in the following cases.
9ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// 1. Optimizes redundant sign extends for the following case
10ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//    Transform the following pattern
11ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//    %vreg170<def> = SXTW %vreg166
12ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//    ...
13ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//    %vreg176<def> = COPY %vreg170:subreg_loreg
14ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
15ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//    Into
16ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//    %vreg176<def> = COPY vreg166
17ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
18ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//  2. Optimizes redundant negation of predicates.
19ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     %vreg15<def> = CMPGTrr %vreg6, %vreg2
20ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     ...
21ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     %vreg16<def> = NOT_p %vreg15<kill>
22ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     ...
23ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     JMP_c %vreg16<kill>, <BB#1>, %PC<imp-def,dead>
24ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
25ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     Into
26ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     %vreg15<def> = CMPGTrr %vreg6, %vreg2;
27ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     ...
28ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//     JMP_cNot %vreg15<kill>, <BB#1>, %PC<imp-def,dead>;
29ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//
30ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// Note: The peephole pass makes the instrucstions like
31ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill>
32ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// redundant and relies on some form of dead removal instrucions, like
33ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// DCE or DIE to actually eliminate them.
34ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
35ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
36ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//===----------------------------------------------------------------------===//
37ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
38ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#define DEBUG_TYPE "hexagon-peephole"
3979aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "Hexagon.h"
4079aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "HexagonTargetMachine.h"
41ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Constants.h"
42ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/PassSupport.h"
43ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/ADT/DenseMap.h"
44ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/ADT/Statistic.h"
45ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/Passes.h"
46ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineFunction.h"
47ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineFunctionPass.h"
48ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineInstrBuilder.h"
49ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineRegisterInfo.h"
5079aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "llvm/Support/CommandLine.h"
51ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Support/Debug.h"
52ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Support/raw_ostream.h"
53ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Target/TargetMachine.h"
54ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Target/TargetRegisterInfo.h"
55ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Target/TargetInstrInfo.h"
56ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include <algorithm>
57ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
58ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandeusing namespace llvm;
59ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
60ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
61ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::Hidden, cl::ZeroOrMore, cl::init(false),
62ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::desc("Disable Peephole Optimization"));
63ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
64ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<int>
65ab7955b9ce3197215406bc9fc97b22074127d035Sirish PandeDbgPNPCount("pnp-count", cl::init(-1), cl::Hidden,
66ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  cl::desc("Maximum number of P=NOT(P) to be optimized"));
67ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
68ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
69ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::Hidden, cl::ZeroOrMore, cl::init(false),
70ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::desc("Disable Optimization of PNotP"));
71ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
72ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
73ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::Hidden, cl::ZeroOrMore, cl::init(false),
74ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::desc("Disable Optimization of Sign/Zero Extends"));
75ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
76ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandenamespace {
77ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  struct HexagonPeephole : public MachineFunctionPass {
78ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const HexagonInstrInfo    *QII;
79ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const HexagonRegisterInfo *QRI;
80ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const MachineRegisterInfo *MRI;
81ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
82ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  public:
83ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    static char ID;
84ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    HexagonPeephole() : MachineFunctionPass(ID) { }
85ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
86ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    bool runOnMachineFunction(MachineFunction &MF);
87ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
88ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const char *getPassName() const {
89ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      return "Hexagon optimize redundant zero and size extends";
90ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    }
91ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
92ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    void getAnalysisUsage(AnalysisUsage &AU) const {
93ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      MachineFunctionPass::getAnalysisUsage(AU);
94ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    }
95ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
96ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  private:
97ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    void ChangeOpInto(MachineOperand &Dst, MachineOperand &Src);
98ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  };
99ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
100ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
101ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandechar HexagonPeephole::ID = 0;
102ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
103ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandebool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
104ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
105ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().
106ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                        getInstrInfo());
107ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget().
108ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                       getRegisterInfo());
109ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  MRI = &MF.getRegInfo();
110ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
111ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  DenseMap<unsigned, unsigned> PeepholeMap;
1124c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar  DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
113ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
114ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  if (DisableHexagonPeephole) return false;
115ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
116ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  // Loop over all of the basic blocks.
117ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
118ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande       MBBb != MBBe; ++MBBb) {
119ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    MachineBasicBlock* MBB = MBBb;
120ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    PeepholeMap.clear();
1214c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar    PeepholeDoubleRegsMap.clear();
122ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
123ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    // Traverse the basic block.
124ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
125ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                     ++MII) {
126ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      MachineInstr *MI = MII;
127ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for sign extends:
128ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // %vreg170<def> = SXTW %vreg166
129ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisableOptSZExt && MI->getOpcode() == Hexagon::SXTW) {
130ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        assert (MI->getNumOperands() == 2);
131ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Dst = MI->getOperand(0);
132ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Src  = MI->getOperand(1);
133ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned DstReg = Dst.getReg();
134ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned SrcReg = Src.getReg();
135ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        // Just handle virtual registers.
136ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
137ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
138ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Map the following:
139ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // %vreg170<def> = SXTW %vreg166
140ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // PeepholeMap[170] = vreg166
141ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          PeepholeMap[DstReg] = SrcReg;
142ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
143ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
144ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
1454c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // Look for this sequence below
1464c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
1474c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
1484c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // and convert into
1494c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // %vregIntReg = COPY %vregDoubleReg0:subreg_hireg.
1504c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      if (MI->getOpcode() == Hexagon::LSRd_ri) {
1514c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        assert(MI->getNumOperands() == 3);
1524c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        MachineOperand &Dst = MI->getOperand(0);
1534c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        MachineOperand &Src1 = MI->getOperand(1);
1544c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        MachineOperand &Src2 = MI->getOperand(2);
1554c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        if (Src2.getImm() != 32)
1564c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar          continue;
1574c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        unsigned DstReg = Dst.getReg();
1584c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        unsigned SrcReg = Src1.getReg();
1594c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        PeepholeDoubleRegsMap[DstReg] =
1604c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar          std::make_pair(*&SrcReg, 1/*Hexagon::subreg_hireg*/);
1614c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      }
1624c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar
163ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for P=NOT(P).
164ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisablePNotP &&
165ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          (MI->getOpcode() == Hexagon::NOT_p)) {
166ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        assert (MI->getNumOperands() == 2);
167ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Dst = MI->getOperand(0);
168ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Src  = MI->getOperand(1);
169ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned DstReg = Dst.getReg();
170ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned SrcReg = Src.getReg();
171ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        // Just handle virtual registers.
172ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
173ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
174ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Map the following:
175ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // %vreg170<def> = NOT_xx %vreg166
176ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // PeepholeMap[170] = vreg166
177ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          PeepholeMap[DstReg] = SrcReg;
178ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
179ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
180ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
181ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for copy:
182ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // %vreg176<def> = COPY %vreg170:subreg_loreg
183ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisableOptSZExt && MI->isCopy()) {
184ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        assert (MI->getNumOperands() == 2);
185ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Dst = MI->getOperand(0);
186ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Src  = MI->getOperand(1);
187ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
188ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        // Make sure we are copying the lower 32 bits.
189ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (Src.getSubReg() != Hexagon::subreg_loreg)
190ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          continue;
191ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
192ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned DstReg = Dst.getReg();
193ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned SrcReg = Src.getReg();
194ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
195ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
196ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Try to find in the map.
197ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
198ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            // Change the 1st operand.
199ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            MI->RemoveOperand(1);
200ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            MI->addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
2014c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar          } else  {
2024c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar            DenseMap<unsigned, std::pair<unsigned, unsigned> >::iterator DI =
2034c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              PeepholeDoubleRegsMap.find(SrcReg);
2044c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar            if (DI != PeepholeDoubleRegsMap.end()) {
2054c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
2064c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              MI->RemoveOperand(1);
2074c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              MI->addOperand(MachineOperand::CreateReg(PeepholeSrc.first,
2084c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isDef*/,
2094c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isImp*/,
2104c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isKill*/,
2114c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isDead*/,
2124c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isUndef*/,
2134c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isEarlyClobber*/,
2144c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       PeepholeSrc.second));
2154c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar            }
216ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          }
217ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
218ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
219ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
220ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for Predicated instructions.
221ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisablePNotP) {
222ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        bool Done = false;
223ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (QII->isPredicated(MI)) {
224ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          MachineOperand &Op0 = MI->getOperand(0);
225ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned Reg0 = Op0.getReg();
226ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
227ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          if (RC0->getID() == Hexagon::PredRegsRegClassID) {
228ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            // Handle instructions that have a prediate register in op0
229ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            // (most cases of predicable instructions).
230ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            if (TargetRegisterInfo::isVirtualRegister(Reg0)) {
231ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              // Try to find in the map.
232ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
233ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                // Change the 1st operand and, flip the opcode.
234ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                MI->getOperand(0).setReg(PeepholeSrc);
235ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                int NewOp = QII->getInvertedPredicatedOpcode(MI->getOpcode());
236ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                MI->setDesc(QII->get(NewOp));
237ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                Done = true;
238ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              }
239ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            }
240ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          }
241ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
242ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
243ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (!Done) {
244ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Handle special instructions.
245ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned Op = MI->getOpcode();
246ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned NewOp = 0;
247ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned PR = 1, S1 = 2, S2 = 3;   // Operand indices.
248ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
249ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          switch (Op) {
250ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_rr:
251ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_ii:
252ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_ii:
253ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_rr:
254ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Op;
255ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
256ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_ri:
257ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::TFR_condset_ir;
258ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
259ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_ir:
260ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::TFR_condset_ri;
261ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
262ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_ri:
263ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::MUX_ir;
264ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
265ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_ir:
266ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::MUX_ri;
267ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
268ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          }
269ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          if (NewOp) {
270ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            unsigned PSrc = MI->getOperand(PR).getReg();
271ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
272ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MI->getOperand(PR).setReg(POrig);
273ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MI->setDesc(QII->get(NewOp));
274ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              // Swap operands S1 and S2.
275ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MachineOperand Op1 = MI->getOperand(S1);
276ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MachineOperand Op2 = MI->getOperand(S2);
277ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              ChangeOpInto(MI->getOperand(S1), Op2);
278ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              ChangeOpInto(MI->getOperand(S2), Op1);
279ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            }
280ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          } // if (NewOp)
281ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        } // if (!Done)
282ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
283ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } // if (!DisablePNotP)
284ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
285ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    } // Instruction
286ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  } // Basic Block
287ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  return true;
288ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
289ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
290ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandevoid HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) {
291ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  assert (&Dst != &Src && "Cannot duplicate into itself");
292ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  switch (Dst.getType()) {
293ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    case MachineOperand::MO_Register:
294ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (Src.isReg()) {
295ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.setReg(Src.getReg());
296ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else if (Src.isImm()) {
297ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.ChangeToImmediate(Src.getImm());
298ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else {
299ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        llvm_unreachable("Unexpected src operand type");
300ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
301ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      break;
302ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
303ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    case MachineOperand::MO_Immediate:
304ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (Src.isImm()) {
305ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.setImm(Src.getImm());
306ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else if (Src.isReg()) {
307ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(),
308ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                             Src.isKill(), Src.isDead(), Src.isUndef(),
309ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                             Src.isDebug());
310ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else {
311ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        llvm_unreachable("Unexpected src operand type");
312ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
313ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      break;
314ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
315ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    default:
316ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      llvm_unreachable("Unexpected dst operand type");
317ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      break;
318ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  }
319ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
320ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
321ab7955b9ce3197215406bc9fc97b22074127d035Sirish PandeFunctionPass *llvm::createHexagonPeephole() {
322ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  return new HexagonPeephole();
323ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
324