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:382
unsigned getReg() const
getReg - Returns the register number.
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:411
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:408
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:422
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.
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:63
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...
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413