LLVM  6.0.0svn
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 // %vreg170<def> = SXTW %vreg166
12 // ...
13 // %vreg176<def> = COPY %vreg170:isub_lo
14 //
15 // Into
16 // %vreg176<def> = COPY vreg166
17 //
18 // 2. Optimizes redundant negation of predicates.
19 // %vreg15<def> = CMPGTrr %vreg6, %vreg2
20 // ...
21 // %vreg16<def> = NOT_p %vreg15<kill>
22 // ...
23 // JMP_c %vreg16<kill>, <BB#1>, %PC<imp-def,dead>
24 //
25 // Into
26 // %vreg15<def> = CMPGTrr %vreg6, %vreg2;
27 // ...
28 // JMP_cNot %vreg15<kill>, <BB#1>, %PC<imp-def,dead>;
29 //
30 // Note: The peephole pass makes the instrucstions like
31 // %vreg170<def> = SXTW %vreg166 or %vreg16<def> = NOT_p %vreg15<kill>
32 // redundant and relies on some form of dead removal instructions, like
33 // DCE or DIE to actually eliminate them.
34 
35 
36 //===----------------------------------------------------------------------===//
37 
38 #include "Hexagon.h"
39 #include "HexagonTargetMachine.h"
40 #include "llvm/ADT/DenseMap.h"
41 #include "llvm/ADT/Statistic.h"
46 #include "llvm/CodeGen/Passes.h"
49 #include "llvm/IR/Constants.h"
50 #include "llvm/PassSupport.h"
52 #include "llvm/Support/Debug.h"
55 #include <algorithm>
56 
57 using namespace llvm;
58 
59 #define DEBUG_TYPE "hexagon-peephole"
60 
61 static cl::opt<bool> DisableHexagonPeephole("disable-hexagon-peephole",
63  cl::desc("Disable Peephole Optimization"));
64 
65 static cl::opt<bool> DisablePNotP("disable-hexagon-pnotp",
67  cl::desc("Disable Optimization of PNotP"));
68 
69 static cl::opt<bool> DisableOptSZExt("disable-hexagon-optszext",
71  cl::desc("Disable Optimization of Sign/Zero Extends"));
72 
73 static cl::opt<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
75  cl::desc("Disable Optimization of extensions to i64."));
76 
77 namespace llvm {
80 }
81 
82 namespace {
83  struct HexagonPeephole : public MachineFunctionPass {
84  const HexagonInstrInfo *QII;
85  const HexagonRegisterInfo *QRI;
86  const MachineRegisterInfo *MRI;
87 
88  public:
89  static char ID;
90  HexagonPeephole() : MachineFunctionPass(ID) {
92  }
93 
94  bool runOnMachineFunction(MachineFunction &MF) override;
95 
96  StringRef getPassName() const override {
97  return "Hexagon optimize redundant zero and size extends";
98  }
99 
100  void getAnalysisUsage(AnalysisUsage &AU) const override {
102  }
103  };
104 }
105 
106 char HexagonPeephole::ID = 0;
107 
108 INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
109  false, false)
110 
111 bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
112  if (skipFunction(*MF.getFunction()))
113  return false;
114 
115  QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
116  QRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
117  MRI = &MF.getRegInfo();
118 
119  DenseMap<unsigned, unsigned> PeepholeMap;
120  DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;
121 
122  if (DisableHexagonPeephole) return false;
123 
124  // Loop over all of the basic blocks.
125  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
126  MBBb != MBBe; ++MBBb) {
127  MachineBasicBlock *MBB = &*MBBb;
128  PeepholeMap.clear();
129  PeepholeDoubleRegsMap.clear();
130 
131  // Traverse the basic block.
132  for (auto I = MBB->begin(), E = MBB->end(), NextI = I; I != E; I = NextI) {
133  NextI = std::next(I);
134  MachineInstr &MI = *I;
135  // Look for sign extends:
136  // %vreg170<def> = SXTW %vreg166
137  if (!DisableOptSZExt && MI.getOpcode() == Hexagon::A2_sxtw) {
138  assert(MI.getNumOperands() == 2);
139  MachineOperand &Dst = MI.getOperand(0);
140  MachineOperand &Src = MI.getOperand(1);
141  unsigned DstReg = Dst.getReg();
142  unsigned SrcReg = Src.getReg();
143  // Just handle virtual registers.
146  // Map the following:
147  // %vreg170<def> = SXTW %vreg166
148  // PeepholeMap[170] = vreg166
149  PeepholeMap[DstReg] = SrcReg;
150  }
151  }
152 
153  // Look for %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
154  // %vreg170:DoublRegs, %vreg169:IntRegs
155  if (!DisableOptExtTo64 && MI.getOpcode() == Hexagon::A4_combineir) {
156  assert(MI.getNumOperands() == 3);
157  MachineOperand &Dst = MI.getOperand(0);
158  MachineOperand &Src1 = MI.getOperand(1);
159  MachineOperand &Src2 = MI.getOperand(2);
160  if (Src1.getImm() != 0)
161  continue;
162  unsigned DstReg = Dst.getReg();
163  unsigned SrcReg = Src2.getReg();
164  PeepholeMap[DstReg] = SrcReg;
165  }
166 
167  // Look for this sequence below
168  // %vregDoubleReg1 = LSRd_ri %vregDoubleReg0, 32
169  // %vregIntReg = COPY %vregDoubleReg1:isub_lo.
170  // and convert into
171  // %vregIntReg = COPY %vregDoubleReg0:isub_hi.
172  if (MI.getOpcode() == Hexagon::S2_lsr_i_p) {
173  assert(MI.getNumOperands() == 3);
174  MachineOperand &Dst = MI.getOperand(0);
175  MachineOperand &Src1 = MI.getOperand(1);
176  MachineOperand &Src2 = MI.getOperand(2);
177  if (Src2.getImm() != 32)
178  continue;
179  unsigned DstReg = Dst.getReg();
180  unsigned SrcReg = Src1.getReg();
181  PeepholeDoubleRegsMap[DstReg] =
182  std::make_pair(*&SrcReg, Hexagon::isub_hi);
183  }
184 
185  // Look for P=NOT(P).
186  if (!DisablePNotP && MI.getOpcode() == Hexagon::C2_not) {
187  assert(MI.getNumOperands() == 2);
188  MachineOperand &Dst = MI.getOperand(0);
189  MachineOperand &Src = MI.getOperand(1);
190  unsigned DstReg = Dst.getReg();
191  unsigned SrcReg = Src.getReg();
192  // Just handle virtual registers.
195  // Map the following:
196  // %vreg170<def> = NOT_xx %vreg166
197  // PeepholeMap[170] = vreg166
198  PeepholeMap[DstReg] = SrcReg;
199  }
200  }
201 
202  // Look for copy:
203  // %vreg176<def> = COPY %vreg170:isub_lo
204  if (!DisableOptSZExt && MI.isCopy()) {
205  assert(MI.getNumOperands() == 2);
206  MachineOperand &Dst = MI.getOperand(0);
207  MachineOperand &Src = MI.getOperand(1);
208 
209  // Make sure we are copying the lower 32 bits.
210  if (Src.getSubReg() != Hexagon::isub_lo)
211  continue;
212 
213  unsigned DstReg = Dst.getReg();
214  unsigned SrcReg = Src.getReg();
217  // Try to find in the map.
218  if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {
219  // Change the 1st operand.
220  MI.RemoveOperand(1);
221  MI.addOperand(MachineOperand::CreateReg(PeepholeSrc, false));
222  } else {
224  PeepholeDoubleRegsMap.find(SrcReg);
225  if (DI != PeepholeDoubleRegsMap.end()) {
226  std::pair<unsigned,unsigned> PeepholeSrc = DI->second;
227  MI.RemoveOperand(1);
229  PeepholeSrc.first, false /*isDef*/, false /*isImp*/,
230  false /*isKill*/, false /*isDead*/, false /*isUndef*/,
231  false /*isEarlyClobber*/, PeepholeSrc.second));
232  }
233  }
234  }
235  }
236 
237  // Look for Predicated instructions.
238  if (!DisablePNotP) {
239  bool Done = false;
240  if (QII->isPredicated(MI)) {
241  MachineOperand &Op0 = MI.getOperand(0);
242  unsigned Reg0 = Op0.getReg();
243  const TargetRegisterClass *RC0 = MRI->getRegClass(Reg0);
244  if (RC0->getID() == Hexagon::PredRegsRegClassID) {
245  // Handle instructions that have a prediate register in op0
246  // (most cases of predicable instructions).
248  // Try to find in the map.
249  if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {
250  // Change the 1st operand and, flip the opcode.
251  MI.getOperand(0).setReg(PeepholeSrc);
252  MRI->clearKillFlags(PeepholeSrc);
253  int NewOp = QII->getInvertedPredicatedOpcode(MI.getOpcode());
254  MI.setDesc(QII->get(NewOp));
255  Done = true;
256  }
257  }
258  }
259  }
260 
261  if (!Done) {
262  // Handle special instructions.
263  unsigned Op = MI.getOpcode();
264  unsigned NewOp = 0;
265  unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices.
266 
267  switch (Op) {
268  case Hexagon::C2_mux:
269  case Hexagon::C2_muxii:
270  NewOp = Op;
271  break;
272  case Hexagon::C2_muxri:
273  NewOp = Hexagon::C2_muxir;
274  break;
275  case Hexagon::C2_muxir:
276  NewOp = Hexagon::C2_muxri;
277  break;
278  }
279  if (NewOp) {
280  unsigned PSrc = MI.getOperand(PR).getReg();
281  if (unsigned POrig = PeepholeMap.lookup(PSrc)) {
282  BuildMI(*MBB, MI.getIterator(), MI.getDebugLoc(),
283  QII->get(NewOp), MI.getOperand(0).getReg())
284  .addReg(POrig)
285  .add(MI.getOperand(S2))
286  .add(MI.getOperand(S1));
287  MRI->clearKillFlags(POrig);
288  MI.eraseFromParent();
289  }
290  } // if (NewOp)
291  } // if (!Done)
292 
293  } // if (!DisablePNotP)
294 
295  } // Instruction
296  } // Basic Block
297  return true;
298 }
299 
301  return new HexagonPeephole();
302 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:268
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
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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)
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:293
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:290
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.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
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:1164
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
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
Definition: MachineInstr.h:857
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:59
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:181
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
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:295