LLVM  9.0.0svn
HexagonPeephole.cpp
Go to the documentation of this file.
1 //===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 // This peephole pass optimizes in the following cases.
8 // 1. Optimizes redundant sign extends for the following case
9 // Transform the following pattern
10 // %170 = SXTW %166
11 // ...
12 // %176 = COPY %170:isub_lo
13 //
14 // Into
15 // %176 = COPY %166
16 //
17 // 2. Optimizes redundant negation of predicates.
18 // %15 = CMPGTrr %6, %2
19 // ...
20 // %16 = NOT_p killed %15
21 // ...
22 // JMP_c killed %16, <%bb.1>, implicit dead %pc
23 //
24 // Into
25 // %15 = CMPGTrr %6, %2;
26 // ...
27 // JMP_cNot killed %15, <%bb.1>, implicit dead %pc;
28 //
29 // Note: The peephole pass makes the instrucstions like
30 // %170 = SXTW %166 or %16 = NOT_p killed %15
31 // redundant and relies on some form of dead removal instructions, like
32 // DCE or DIE to actually eliminate them.
33 
34 //===----------------------------------------------------------------------===//
35 
36 #include "Hexagon.h"
37 #include "HexagonTargetMachine.h"
38 #include "llvm/ADT/DenseMap.h"
39 #include "llvm/ADT/Statistic.h"
44 #include "llvm/CodeGen/Passes.h"
47 #include "llvm/IR/Constants.h"
48 #include "llvm/PassSupport.h"
50 #include "llvm/Support/Debug.h"
53 #include <algorithm>
54 
55 using namespace llvm;
56 
57 #define DEBUG_TYPE "hexagon-peephole"
58 
59 static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
61  cl::desc("Disable Peephole Optimization"));
62 
63 static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
65  cl::desc("Disable Optimization of PNotP"));
66 
67 static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
69  cl::desc("Disable Optimization of Sign/Zero Extends"));
70 
71 static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
73  cl::desc("Disable Optimization of extensions to i64."));
74 
75 namespace llvm {
78 }
79 
80 namespace {
81  struct HexagonPeephole : public MachineFunctionPass {
82  const HexagonInstrInfo *QII;
83  const HexagonRegisterInfo *QRI;
84  const MachineRegisterInfo *MRI;
85 
86  public:
87  static char ID;
88  HexagonPeephole() : MachineFunctionPass(ID) {
90  }
91 
92  bool runOnMachineFunction(MachineFunction &MF) override;
93 
94  StringRef getPassName() const override {
95  return "Hexagon optimize redundant zero and size extends";
96  }
97 
98  void getAnalysisUsage(AnalysisUsage &AU) const override {
100  }
101  };
102 }
103 
104 char HexagonPeephole::ID = 0;
105 
106 INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
107  false, false)
108 
109 bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
110  if (skipFunction(MF.getFunction()))
111  return false;
112 
113  QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
114  QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
115  MRI = &MF.getRegInfo();
116 
117  DenseMap<unsigned, unsigned> PeepholeMap;
118  DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
119 
120  if (DisableHexagonPeephole) return false;
121 
122  // Loop over all of the basic blocks.
123  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
124  MBBb != MBBe; ++MBBb) {
125  MachineBasicBlock *MBB = &*MBBb;
126  PeepholeMap.clear();
127  PeepholeDoubleRegsMap.clear();
128 
129  // Traverse the basic block.
130  for (auto I = MBB->begin(), E = MBB->end(), NextI = I; I != E; I = NextI) {
131  NextI = std::next(I);
132  MachineInstr &MI = *I;
133  // Look for sign extends:
134  // %170 = SXTW %166
135  if (!DisableOptSZExt && MI.getOpcode() == Hexagon::A2_sxtw) {
136  assert(MI.getNumOperands() == 2);
137  MachineOperand &Dst = MI.getOperand(0);
138  MachineOperand &Src = MI.getOperand(1);
139  unsigned DstReg = Dst.getReg();
140  unsigned SrcReg = Src.getReg();
141  // Just handle virtual registers.
144  // Map the following:
145  // %170 = SXTW %166
146  // PeepholeMap[170] = %166
147  PeepholeMap[DstReg] = SrcReg;
148  }
149  }
150 
151  // Look for %170 = COMBINE_ir_V4 (0, %169)
152  // %170:DoublRegs, %169:IntRegs
153  if (!DisableOptExtTo64 && MI.getOpcode() == Hexagon::A4_combineir) {
154  assert(MI.getNumOperands() == 3);
155  MachineOperand &Dst = MI.getOperand(0);
156  MachineOperand &Src1 = MI.getOperand(1);
157  MachineOperand &Src2 = MI.getOperand(2);
158  if (Src1.getImm() != 0)
159  continue;
160  unsigned DstReg = Dst.getReg();
161  unsigned SrcReg = Src2.getReg();
162  PeepholeMap[DstReg] = SrcReg;
163  }
164 
165  // Look for this sequence below
166  // %DoubleReg1 = LSRd_ri %DoubleReg0, 32
167  // %IntReg = COPY %DoubleReg1:isub_lo.
168  // and convert into
169  // %IntReg = COPY %DoubleReg0:isub_hi.
170  if (MI.getOpcode() == Hexagon::S2_lsr_i_p) {
171  assert(MI.getNumOperands() == 3);
172  MachineOperand &Dst = MI.getOperand(0);
173  MachineOperand &Src1 = MI.getOperand(1);
174  MachineOperand &Src2 = MI.getOperand(2);
175  if (Src2.getImm() != 32)
176  continue;
177  unsigned DstReg = Dst.getReg();
178  unsigned SrcReg = Src1.getReg();
179  PeepholeDoubleRegsMap[DstReg] =
180  std::make_pair(*&SrcReg, Hexagon::isub_hi);
181  }
182 
183  // Look for P=NOT(P).
184  if (!DisablePNotP && MI.getOpcode() == Hexagon::C2_not) {
185  assert(MI.getNumOperands() == 2);
186  MachineOperand &Dst = MI.getOperand(0);
187  MachineOperand &Src = MI.getOperand(1);
188  unsigned DstReg = Dst.getReg();
189  unsigned SrcReg = Src.getReg();
190  // Just handle virtual registers.
193  // Map the following:
194  // %170 = NOT_xx %166
195  // PeepholeMap[170] = %166
196  PeepholeMap[DstReg] = SrcReg;
197  }
198  }
199 
200  // Look for copy:
201  // %176 = COPY %170:isub_lo
202  if (!DisableOptSZExt && MI.isCopy()) {
203  assert(MI.getNumOperands() == 2);
204  MachineOperand &Dst = MI.getOperand(0);
205  MachineOperand &Src = MI.getOperand(1);
206 
207  // Make sure we are copying the lower 32 bits.
208  if (Src.getSubReg() != Hexagon::isub_lo)
209  continue;
210 
211  unsigned DstReg = Dst.getReg();
212  unsigned SrcReg = Src.getReg();
215  // Try to find in the map.
216  if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
217  // Change the 1st operand.
218  MI.RemoveOperand(1);
219  MI.addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
220  } else {
222  PeepholeDoubleRegsMap.find(SrcReg);
223  if (DI != PeepholeDoubleRegsMap.end()) {
224  std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
225  MI.RemoveOperand(1);
227  PeepholeSrc.first, false /*isDef*/, false /*isImp*/,
228  false /*isKill*/, false /*isDead*/, false /*isUndef*/,
229  false /*isEarlyClobber*/, PeepholeSrc.second));
230  }
231  }
232  }
233  }
234 
235  // Look for Predicated instructions.
236  if (!DisablePNotP) {
237  bool Done = false;
238  if (QII->isPredicated(MI)) {
239  MachineOperand &Op0 = MI.getOperand(0);
240  unsigned Reg0 = Op0.getReg();
241  const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
242  if (RC0->getID() == Hexagon::PredRegsRegClassID) {
243  // Handle instructions that have a prediate register in op0
244  // (most cases of predicable instructions).
246  // Try to find in the map.
247  if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
248  // Change the 1st operand and, flip the opcode.
249  MI.getOperand(0).setReg(PeepholeSrc);
250  MRI->clearKillFlags(PeepholeSrc);
251  int NewOp = QII->getInvertedPredicatedOpcode(MI.getOpcode());
252  MI.setDesc(QII->get(NewOp));
253  Done = true;
254  }
255  }
256  }
257  }
258 
259  if (!Done) {
260  // Handle special instructions.
261  unsigned Op = MI.getOpcode();
262  unsigned NewOp = 0;
263  unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices.
264 
265  switch (Op) {
266  case Hexagon::C2_mux:
267  case Hexagon::C2_muxii:
268  NewOp = Op;
269  break;
270  case Hexagon::C2_muxri:
271  NewOp = Hexagon::C2_muxir;
272  break;
273  case Hexagon::C2_muxir:
274  NewOp = Hexagon::C2_muxri;
275  break;
276  }
277  if (NewOp) {
278  unsigned PSrc = MI.getOperand(PR).getReg();
279  if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
280  BuildMI(*MBB, MI.getIterator(), MI.getDebugLoc(),
281  QII->get(NewOp), MI.getOperand(0).getReg())
282  .addReg(POrig)
283  .add(MI.getOperand(S2))
284  .add(MI.getOperand(S1));
285  MRI->clearKillFlags(POrig);
286  MI.eraseFromParent();
287  }
288  } // if (NewOp)
289  } // if (!Done)
290 
291  } // if (!DisablePNotP)
292 
293  } // Instruction
294  } // Basic Block
295  return true;
296 }
297 
299  return new HexagonPeephole();
300 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned getSubReg() const
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole", false, false) bool HexagonPeephole
static cl::opt< bool > DisablePNotP("disable-hexagon-pnotp", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable Optimization of PNotP"))
unsigned getID() const
Return the register class ID number.
static cl::opt< bool > DisableOptSZExt("disable-hexagon-optszext", cl::Hidden, cl::ZeroOrMore, cl::init(true), cl::desc("Disable Optimization of Sign/Zero Extends"))
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1165
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
self_iterator getIterator()
Definition: ilist_node.h:81
bool isCopy() const
void initializeHexagonPeepholePass(PassRegistry &)
Iterator for intrusive lists based on ilist_node.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:218
MachineOperand class - Representation of each machine instruction operand.
FunctionPass * createHexagonPeephole()
int64_t getImm() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:64
static cl::opt< bool > DisableHexagonPeephole("disable-hexagon-peephole", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable Peephole Optimization"))
void setReg(unsigned Reg)
Change the register this operand corresponds to.
#define I(x, y, z)
Definition: MD5.cpp:58
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:211
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > DisableOptExtTo64("disable-hexagon-opt-ext-to-64", cl::Hidden, cl::ZeroOrMore, cl::init(true), cl::desc("Disable Optimization of extensions to i64."))
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416