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>
323f4f420ab7acb10221ba971543a7eed5489fb626Robert Wilhelm// redundant and relies on some form of dead removal instructions, like
33ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande// DCE or DIE to actually eliminate them.
34ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
35ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
36ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande//===----------------------------------------------------------------------===//
37ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
3879aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "Hexagon.h"
3979aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "HexagonTargetMachine.h"
40ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/ADT/DenseMap.h"
41ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/ADT/Statistic.h"
42ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineFunction.h"
43ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineFunctionPass.h"
44ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineInstrBuilder.h"
45ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/CodeGen/MachineRegisterInfo.h"
46d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/Passes.h"
470b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
48d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/PassSupport.h"
4979aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "llvm/Support/CommandLine.h"
50ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Support/Debug.h"
51ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Support/raw_ostream.h"
52d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h"
53ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Target/TargetMachine.h"
54ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include "llvm/Target/TargetRegisterInfo.h"
55ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande#include <algorithm>
56ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
57ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandeusing namespace llvm;
58ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "hexagon-peephole"
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
61ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
62ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::Hidden, cl::ZeroOrMore, cl::init(false),
63ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::desc("Disable Peephole Optimization"));
64ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
65ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
66ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::Hidden, cl::ZeroOrMore, cl::init(false),
67ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::desc("Disable Optimization of PNotP"));
68ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
69ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandestatic cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
70ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::Hidden, cl::ZeroOrMore, cl::init(false),
71ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    cl::desc("Disable Optimization of Sign/Zero Extends"));
72ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
7302d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkarstatic cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
7402d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar    cl::Hidden, cl::ZeroOrMore, cl::init(false),
7502d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar    cl::desc("Disable Optimization of extensions to i64."));
7602d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar
77942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszeknamespace llvm {
78942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek  void initializeHexagonPeepholePass(PassRegistry&);
79942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek}
80942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek
81ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandenamespace {
82ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  struct HexagonPeephole : public MachineFunctionPass {
83ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const HexagonInstrInfo    *QII;
84ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const HexagonRegisterInfo *QRI;
85ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    const MachineRegisterInfo *MRI;
86ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
87ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  public:
88ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    static char ID;
89942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek    HexagonPeephole() : MachineFunctionPass(ID) {
90942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek      initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
91942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek    }
92ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool runOnMachineFunction(MachineFunction &MF) override;
94ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const char *getPassName() const override {
96ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      return "Hexagon optimize redundant zero and size extends";
97ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    }
98ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    void getAnalysisUsage(AnalysisUsage &AU) const override {
100ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      MachineFunctionPass::getAnalysisUsage(AU);
101ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    }
102ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
103ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  private:
104ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    void ChangeOpInto(MachineOperand &Dst, MachineOperand &Src);
105ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  };
106ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
107ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
108ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandechar HexagonPeephole::ID = 0;
109ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
110942940a3262242ac55efea88f818959f28d18bbaKrzysztof ParzyszekINITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
111942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszek                false, false)
112ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
113942940a3262242ac55efea88f818959f28d18bbaKrzysztof Parzyszekbool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
114ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().
115ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                        getInstrInfo());
116ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget().
117ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                       getRegisterInfo());
118ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  MRI = &MF.getRegInfo();
119ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
120ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  DenseMap<unsigned, unsigned> PeepholeMap;
1214c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar  DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
122ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
123ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  if (DisableHexagonPeephole) return false;
124ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
125ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  // Loop over all of the basic blocks.
126ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
127ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande       MBBb != MBBe; ++MBBb) {
128ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    MachineBasicBlock* MBB = MBBb;
129ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    PeepholeMap.clear();
1304c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar    PeepholeDoubleRegsMap.clear();
131ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
132ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    // Traverse the basic block.
133ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
134ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                                     ++MII) {
135ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      MachineInstr *MI = MII;
136ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for sign extends:
137ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // %vreg170<def> = SXTW %vreg166
138ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisableOptSZExt && MI->getOpcode() == Hexagon::SXTW) {
139ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        assert (MI->getNumOperands() == 2);
140ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Dst = MI->getOperand(0);
141ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Src  = MI->getOperand(1);
142ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned DstReg = Dst.getReg();
143ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned SrcReg = Src.getReg();
144ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        // Just handle virtual registers.
145ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
146ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
147ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Map the following:
148ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // %vreg170<def> = SXTW %vreg166
149ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // PeepholeMap[170] = vreg166
150ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          PeepholeMap[DstReg] = SrcReg;
151ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
152ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
153ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
15402d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar      // Look for  %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
15502d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar      // %vreg170:DoublRegs, %vreg169:IntRegs
15602d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar      if (!DisableOptExtTo64 &&
15702d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar          MI->getOpcode () == Hexagon::COMBINE_Ir_V4) {
15802d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        assert (MI->getNumOperands() == 3);
15902d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        MachineOperand &Dst = MI->getOperand(0);
16002d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        MachineOperand &Src1 = MI->getOperand(1);
16102d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        MachineOperand &Src2 = MI->getOperand(2);
16202d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        if (Src1.getImm() != 0)
16302d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar          continue;
16402d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        unsigned DstReg = Dst.getReg();
16502d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        unsigned SrcReg = Src2.getReg();
16602d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar        PeepholeMap[DstReg] = SrcReg;
16702d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar      }
16802d937d86420409210291accd9aa023d97b4a8b5Pranav Bhandarkar
1694c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // Look for this sequence below
1704c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
1714c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
1724c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // and convert into
1734c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      // %vregIntReg = COPY %vregDoubleReg0:subreg_hireg.
1744c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      if (MI->getOpcode() == Hexagon::LSRd_ri) {
1754c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        assert(MI->getNumOperands() == 3);
1764c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        MachineOperand &Dst = MI->getOperand(0);
1774c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        MachineOperand &Src1 = MI->getOperand(1);
1784c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        MachineOperand &Src2 = MI->getOperand(2);
1794c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        if (Src2.getImm() != 32)
1804c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar          continue;
1814c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        unsigned DstReg = Dst.getReg();
1824c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        unsigned SrcReg = Src1.getReg();
1834c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar        PeepholeDoubleRegsMap[DstReg] =
1844c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar          std::make_pair(*&SrcReg, 1/*Hexagon::subreg_hireg*/);
1854c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar      }
1864c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar
187ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for P=NOT(P).
188ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisablePNotP &&
189ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          (MI->getOpcode() == Hexagon::NOT_p)) {
190ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        assert (MI->getNumOperands() == 2);
191ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Dst = MI->getOperand(0);
192ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Src  = MI->getOperand(1);
193ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned DstReg = Dst.getReg();
194ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned SrcReg = Src.getReg();
195ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        // Just handle virtual registers.
196ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
197ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
198ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Map the following:
199ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // %vreg170<def> = NOT_xx %vreg166
200ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // PeepholeMap[170] = vreg166
201ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          PeepholeMap[DstReg] = SrcReg;
202ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
203ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
204ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
205ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for copy:
206ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // %vreg176<def> = COPY %vreg170:subreg_loreg
207ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisableOptSZExt && MI->isCopy()) {
208ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        assert (MI->getNumOperands() == 2);
209ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Dst = MI->getOperand(0);
210ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        MachineOperand &Src  = MI->getOperand(1);
211ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
212ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        // Make sure we are copying the lower 32 bits.
213ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (Src.getSubReg() != Hexagon::subreg_loreg)
214ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          continue;
215ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
216ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned DstReg = Dst.getReg();
217ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        unsigned SrcReg = Src.getReg();
218ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (TargetRegisterInfo::isVirtualRegister(DstReg) &&
219ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            TargetRegisterInfo::isVirtualRegister(SrcReg)) {
220ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Try to find in the map.
221ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
222ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            // Change the 1st operand.
223ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            MI->RemoveOperand(1);
224ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            MI->addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
2254c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar          } else  {
2264c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar            DenseMap<unsigned, std::pair<unsigned, unsigned> >::iterator DI =
2274c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              PeepholeDoubleRegsMap.find(SrcReg);
2284c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar            if (DI != PeepholeDoubleRegsMap.end()) {
2294c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
2304c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              MI->RemoveOperand(1);
2314c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar              MI->addOperand(MachineOperand::CreateReg(PeepholeSrc.first,
2324c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isDef*/,
2334c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isImp*/,
2344c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isKill*/,
2354c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isDead*/,
2364c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isUndef*/,
2374c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       false /*isEarlyClobber*/,
2384c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar                                                       PeepholeSrc.second));
2394c3d3ecdf83cc85e81f2146f2942cf6931e9ce18Pranav Bhandarkar            }
240ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          }
241ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
242ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
243ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
244ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      // Look for Predicated instructions.
245ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (!DisablePNotP) {
246ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        bool Done = false;
247ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (QII->isPredicated(MI)) {
248ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          MachineOperand &Op0 = MI->getOperand(0);
249ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned Reg0 = Op0.getReg();
250ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
251ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          if (RC0->getID() == Hexagon::PredRegsRegClassID) {
252ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            // Handle instructions that have a prediate register in op0
253ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            // (most cases of predicable instructions).
254ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            if (TargetRegisterInfo::isVirtualRegister(Reg0)) {
255ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              // Try to find in the map.
256ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
257ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                // Change the 1st operand and, flip the opcode.
258ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                MI->getOperand(0).setReg(PeepholeSrc);
259ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                int NewOp = QII->getInvertedPredicatedOpcode(MI->getOpcode());
260ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                MI->setDesc(QII->get(NewOp));
261ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                Done = true;
262ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              }
263ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            }
264ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          }
265ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        }
266ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
267ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        if (!Done) {
268ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          // Handle special instructions.
269ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned Op = MI->getOpcode();
270ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned NewOp = 0;
271ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          unsigned PR = 1, S1 = 2, S2 = 3;   // Operand indices.
272ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
273ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          switch (Op) {
274ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_rr:
275ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_ii:
276ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_ii:
277ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_rr:
278ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Op;
279ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
280ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_ri:
281ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::TFR_condset_ir;
282ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
283ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::TFR_condset_ir:
284ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::TFR_condset_ri;
285ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
286ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_ri:
287ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::MUX_ir;
288ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
289ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            case Hexagon::MUX_ir:
290ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              NewOp = Hexagon::MUX_ri;
291ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              break;
292ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          }
293ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          if (NewOp) {
294ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            unsigned PSrc = MI->getOperand(PR).getReg();
295ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
296ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MI->getOperand(PR).setReg(POrig);
297ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MI->setDesc(QII->get(NewOp));
298ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              // Swap operands S1 and S2.
299ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MachineOperand Op1 = MI->getOperand(S1);
300ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              MachineOperand Op2 = MI->getOperand(S2);
301ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              ChangeOpInto(MI->getOperand(S1), Op2);
302ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande              ChangeOpInto(MI->getOperand(S2), Op1);
303ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande            }
304ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande          } // if (NewOp)
305ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        } // if (!Done)
306ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
307ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } // if (!DisablePNotP)
308ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
309ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    } // Instruction
310ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  } // Basic Block
311ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  return true;
312ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
313ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
314ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pandevoid HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) {
315ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  assert (&Dst != &Src && "Cannot duplicate into itself");
316ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  switch (Dst.getType()) {
317ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    case MachineOperand::MO_Register:
318ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (Src.isReg()) {
319ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.setReg(Src.getReg());
320ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else if (Src.isImm()) {
321ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.ChangeToImmediate(Src.getImm());
322ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else {
323ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        llvm_unreachable("Unexpected src operand type");
324ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
325ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      break;
326ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
327ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    case MachineOperand::MO_Immediate:
328ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      if (Src.isImm()) {
329ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.setImm(Src.getImm());
330ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else if (Src.isReg()) {
331ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(),
332ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                             Src.isKill(), Src.isDead(), Src.isUndef(),
333ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande                             Src.isDebug());
334ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      } else {
335ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande        llvm_unreachable("Unexpected src operand type");
336ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      }
337ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      break;
338ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
339ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande    default:
340ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      llvm_unreachable("Unexpected dst operand type");
341ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      break;
342ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  }
343ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
344ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande
345ab7955b9ce3197215406bc9fc97b22074127d035Sirish PandeFunctionPass *llvm::createHexagonPeephole() {
346ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  return new HexagonPeephole();
347ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande}
348