LLVM  8.0.1
HexagonPeephole.cpp
Go to the documentation of this file.
1 //===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 // This peephole pass optimizes in the following cases.
9 // 1. Optimizes redundant sign extends for the following case
10 // Transform the following pattern
11 // %170 = SXTW %166
12 // ...
13 // %176 = COPY %170:isub_lo
14 //
15 // Into
16 // %176 = COPY %166
17 //
18 // 2. Optimizes redundant negation of predicates.
19 // %15 = CMPGTrr %6, %2
20 // ...
21 // %16 = NOT_p killed %15
22 // ...
23 // JMP_c killed %16, <%bb.1>, implicit dead %pc
24 //
25 // Into
26 // %15 = CMPGTrr %6, %2;
27 // ...
28 // JMP_cNot killed %15, <%bb.1>, implicit dead %pc;
29 //
30 // Note: The peephole pass makes the instrucstions like
31 // %170 = SXTW %166 or %16 = NOT_p killed %15
32 // redundant and relies on some form of dead removal instructions, like
33 // DCE or DIE to actually eliminate them.
34 
35 //===----------------------------------------------------------------------===//
36 
37 #include "Hexagon.h"
38 #include "HexagonTargetMachine.h"
39 #include "llvm/ADT/DenseMap.h"
40 #include "llvm/ADT/Statistic.h"
45 #include "llvm/CodeGen/Passes.h"
48 #include "llvm/IR/Constants.h"
49 #include "llvm/PassSupport.h"
51 #include "llvm/Support/Debug.h"
54 #include <algorithm>
55 
56 using namespace llvm;
57 
58 #define DEBUG_TYPE "hexagon-peephole"
59 
60 static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
62  cl::desc("Disable Peephole Optimization"));
63 
64 static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
66  cl::desc("Disable Optimization of PNotP"));
67 
68 static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
70  cl::desc("Disable Optimization of Sign/Zero Extends"));
71 
72 static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
74  cl::desc("Disable Optimization of extensions to i64."));
75 
76 namespace llvm {
79 }
80 
81 namespace {
82  struct HexagonPeephole : public MachineFunctionPass {
83  const HexagonInstrInfo *QII;
84  const HexagonRegisterInfo *QRI;
85  const MachineRegisterInfo *MRI;
86 
87  public:
88  static char ID;
89  HexagonPeephole() : MachineFunctionPass(ID) {
91  }
92 
93  bool runOnMachineFunction(MachineFunction &MF) override;
94 
95  StringRef getPassName() const override {
96  return "Hexagon optimize redundant zero and size extends";
97  }
98 
99  void getAnalysisUsage(AnalysisUsage &AU) const override {
101  }
102  };
103 }
104 
105 char HexagonPeephole::ID = 0;
106 
107 INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
108  false, false)
109 
110 bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
111  if (skipFunction(MF.getFunction()))
112  return false;
113 
114  QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
115  QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
116  MRI = &MF.getRegInfo();
117 
118  DenseMap<unsigned, unsigned> PeepholeMap;
119  DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
120 
121  if (DisableHexagonPeephole) return false;
122 
123  // Loop over all of the basic blocks.
124  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
125  MBBb != MBBe; ++MBBb) {
126  MachineBasicBlock *MBB = &*MBBb;
127  PeepholeMap.clear();
128  PeepholeDoubleRegsMap.clear();
129 
130  // Traverse the basic block.
131  for (auto I = MBB->begin(), E = MBB->end(), NextI = I; I != E; I = NextI) {
132  NextI = std::next(I);
133  MachineInstr &MI = *I;
134  // Look for sign extends:
135  // %170 = SXTW %166
136  if (!DisableOptSZExt && MI.getOpcode() == Hexagon::A2_sxtw) {
137  assert(MI.getNumOperands() == 2);
138  MachineOperand &Dst = MI.getOperand(0);
139  MachineOperand &Src = MI.getOperand(1);
140  unsigned DstReg = Dst.getReg();
141  unsigned SrcReg = Src.getReg();
142  // Just handle virtual registers.
145  // Map the following:
146  // %170 = SXTW %166
147  // PeepholeMap[170] = %166
148  PeepholeMap[DstReg] = SrcReg;
149  }
150  }
151 
152  // Look for %170 = COMBINE_ir_V4 (0, %169)
153  // %170:DoublRegs, %169:IntRegs
154  if (!DisableOptExtTo64 && MI.getOpcode() == Hexagon::A4_combineir) {
155  assert(MI.getNumOperands() == 3);
156  MachineOperand &Dst = MI.getOperand(0);
157  MachineOperand &Src1 = MI.getOperand(1);
158  MachineOperand &Src2 = MI.getOperand(2);
159  if (Src1.getImm() != 0)
160  continue;
161  unsigned DstReg = Dst.getReg();
162  unsigned SrcReg = Src2.getReg();
163  PeepholeMap[DstReg] = SrcReg;
164  }
165 
166  // Look for this sequence below
167  // %DoubleReg1 = LSRd_ri %DoubleReg0, 32
168  // %IntReg = COPY %DoubleReg1:isub_lo.
169  // and convert into
170  // %IntReg = COPY %DoubleReg0:isub_hi.
171  if (MI.getOpcode() == Hexagon::S2_lsr_i_p) {
172  assert(MI.getNumOperands() == 3);
173  MachineOperand &Dst = MI.getOperand(0);
174  MachineOperand &Src1 = MI.getOperand(1);
175  MachineOperand &Src2 = MI.getOperand(2);
176  if (Src2.getImm() != 32)
177  continue;
178  unsigned DstReg = Dst.getReg();
179  unsigned SrcReg = Src1.getReg();
180  PeepholeDoubleRegsMap[DstReg] =
181  std::make_pair(*&SrcReg, Hexagon::isub_hi);
182  }
183 
184  // Look for P=NOT(P).
185  if (!DisablePNotP && MI.getOpcode() == Hexagon::C2_not) {
186  assert(MI.getNumOperands() == 2);
187  MachineOperand &Dst = MI.getOperand(0);
188  MachineOperand &Src = MI.getOperand(1);
189  unsigned DstReg = Dst.getReg();
190  unsigned SrcReg = Src.getReg();
191  // Just handle virtual registers.
194  // Map the following:
195  // %170 = NOT_xx %166
196  // PeepholeMap[170] = %166
197  PeepholeMap[DstReg] = SrcReg;
198  }
199  }
200 
201  // Look for copy:
202  // %176 = COPY %170:isub_lo
203  if (!DisableOptSZExt && MI.isCopy()) {
204  assert(MI.getNumOperands() == 2);
205  MachineOperand &Dst = MI.getOperand(0);
206  MachineOperand &Src = MI.getOperand(1);
207 
208  // Make sure we are copying the lower 32 bits.
209  if (Src.getSubReg() != Hexagon::isub_lo)
210  continue;
211 
212  unsigned DstReg = Dst.getReg();
213  unsigned SrcReg = Src.getReg();
216  // Try to find in the map.
217  if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
218  // Change the 1st operand.
219  MI.RemoveOperand(1);
220  MI.addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
221  } else {
223  PeepholeDoubleRegsMap.find(SrcReg);
224  if (DI != PeepholeDoubleRegsMap.end()) {
225  std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
226  MI.RemoveOperand(1);
228  PeepholeSrc.first, false /*isDef*/, false /*isImp*/,
229  false /*isKill*/, false /*isDead*/, false /*isUndef*/,
230  false /*isEarlyClobber*/, PeepholeSrc.second));
231  }
232  }
233  }
234  }
235 
236  // Look for Predicated instructions.
237  if (!DisablePNotP) {
238  bool Done = false;
239  if (QII->isPredicated(MI)) {
240  MachineOperand &Op0 = MI.getOperand(0);
241  unsigned Reg0 = Op0.getReg();
242  const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
243  if (RC0->getID() == Hexagon::PredRegsRegClassID) {
244  // Handle instructions that have a prediate register in op0
245  // (most cases of predicable instructions).
247  // Try to find in the map.
248  if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
249  // Change the 1st operand and, flip the opcode.
250  MI.getOperand(0).setReg(PeepholeSrc);
251  MRI->clearKillFlags(PeepholeSrc);
252  int NewOp = QII->getInvertedPredicatedOpcode(MI.getOpcode());
253  MI.setDesc(QII->get(NewOp));
254  Done = true;
255  }
256  }
257  }
258  }
259 
260  if (!Done) {
261  // Handle special instructions.
262  unsigned Op = MI.getOpcode();
263  unsigned NewOp = 0;
264  unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices.
265 
266  switch (Op) {
267  case Hexagon::C2_mux:
268  case Hexagon::C2_muxii:
269  NewOp = Op;
270  break;
271  case Hexagon::C2_muxri:
272  NewOp = Hexagon::C2_muxir;
273  break;
274  case Hexagon::C2_muxir:
275  NewOp = Hexagon::C2_muxri;
276  break;
277  }
278  if (NewOp) {
279  unsigned PSrc = MI.getOperand(PR).getReg();
280  if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
281  BuildMI(*MBB, MI.getIterator(), MI.getDebugLoc(),
282  QII->get(NewOp), MI.getOperand(0).getReg())
283  .addReg(POrig)
284  .add(MI.getOperand(S2))
285  .add(MI.getOperand(S1));
286  MRI->clearKillFlags(POrig);
287  MI.eraseFromParent();
288  }
289  } // if (NewOp)
290  } // if (!Done)
291 
292  } // if (!DisablePNotP)
293 
294  } // Instruction
295  } // Basic Block
296  return true;
297 }
298 
300  return new HexagonPeephole();
301 }
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:24
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
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:412
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:409
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:1166
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:423
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:285
self_iterator getIterator()
Definition: ilist_node.h:82
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: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:49
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:39
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:414