LLVM  8.0.1
OptimizePHIs.cpp
Go to the documentation of this file.
1 //===- OptimizePHIs.cpp - Optimize machine instruction PHIs ---------------===//
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 //===----------------------------------------------------------------------===//
9 //
10 // This pass optimizes machine instruction PHIs to take advantage of
11 // opportunities created during DAG legalization.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/ADT/Statistic.h"
25 #include "llvm/Pass.h"
26 #include <cassert>
27 
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "opt-phis"
31 
32 STATISTIC(NumPHICycles, "Number of PHI cycles replaced");
33 STATISTIC(NumDeadPHICycles, "Number of dead PHI cycles");
34 
35 namespace {
36 
37  class OptimizePHIs : public MachineFunctionPass {
39  const TargetInstrInfo *TII;
40 
41  public:
42  static char ID; // Pass identification
43 
44  OptimizePHIs() : MachineFunctionPass(ID) {
46  }
47 
48  bool runOnMachineFunction(MachineFunction &Fn) override;
49 
50  void getAnalysisUsage(AnalysisUsage &AU) const override {
51  AU.setPreservesCFG();
53  }
54 
55  private:
56  using InstrSet = SmallPtrSet<MachineInstr *, 16>;
57  using InstrSetIterator = SmallPtrSetIterator<MachineInstr *>;
58 
59  bool IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg,
60  InstrSet &PHIsInCycle);
61  bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle);
62  bool OptimizeBB(MachineBasicBlock &MBB);
63  };
64 
65 } // end anonymous namespace
66 
67 char OptimizePHIs::ID = 0;
68 
70 
72  "Optimize machine instruction PHIs", false, false)
73 
74 bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) {
75  if (skipFunction(Fn.getFunction()))
76  return false;
77 
78  MRI = &Fn.getRegInfo();
79  TII = Fn.getSubtarget().getInstrInfo();
80 
81  // Find dead PHI cycles and PHI cycles that can be replaced by a single
82  // value. InstCombine does these optimizations, but DAG legalization may
83  // introduce new opportunities, e.g., when i64 values are split up for
84  // 32-bit targets.
85  bool Changed = false;
86  for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
87  Changed |= OptimizeBB(*I);
88 
89  return Changed;
90 }
91 
92 /// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands
93 /// are copies of SingleValReg, possibly via copies through other PHIs. If
94 /// SingleValReg is zero on entry, it is set to the register with the single
95 /// non-copy value. PHIsInCycle is a set used to keep track of the PHIs that
96 /// have been scanned. PHIs may be grouped by cycle, several cycles or chains.
97 bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI,
98  unsigned &SingleValReg,
99  InstrSet &PHIsInCycle) {
100  assert(MI->isPHI() && "IsSingleValuePHICycle expects a PHI instruction");
101  unsigned DstReg = MI->getOperand(0).getReg();
102 
103  // See if we already saw this register.
104  if (!PHIsInCycle.insert(MI).second)
105  return true;
106 
107  // Don't scan crazily complex things.
108  if (PHIsInCycle.size() == 16)
109  return false;
110 
111  // Scan the PHI operands.
112  for (unsigned i = 1; i != MI->getNumOperands(); i += 2) {
113  unsigned SrcReg = MI->getOperand(i).getReg();
114  if (SrcReg == DstReg)
115  continue;
116  MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
117 
118  // Skip over register-to-register moves.
119  if (SrcMI && SrcMI->isCopy() &&
120  !SrcMI->getOperand(0).getSubReg() &&
121  !SrcMI->getOperand(1).getSubReg() &&
123  SrcReg = SrcMI->getOperand(1).getReg();
124  SrcMI = MRI->getVRegDef(SrcReg);
125  }
126  if (!SrcMI)
127  return false;
128 
129  if (SrcMI->isPHI()) {
130  if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle))
131  return false;
132  } else {
133  // Fail if there is more than one non-phi/non-move register.
134  if (SingleValReg != 0 && SingleValReg != SrcReg)
135  return false;
136  SingleValReg = SrcReg;
137  }
138  }
139  return true;
140 }
141 
142 /// IsDeadPHICycle - Check if the register defined by a PHI is only used by
143 /// other PHIs in a cycle.
144 bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) {
145  assert(MI->isPHI() && "IsDeadPHICycle expects a PHI instruction");
146  unsigned DstReg = MI->getOperand(0).getReg();
148  "PHI destination is not a virtual register");
149 
150  // See if we already saw this register.
151  if (!PHIsInCycle.insert(MI).second)
152  return true;
153 
154  // Don't scan crazily complex things.
155  if (PHIsInCycle.size() == 16)
156  return false;
157 
158  for (MachineInstr &UseMI : MRI->use_nodbg_instructions(DstReg)) {
159  if (!UseMI.isPHI() || !IsDeadPHICycle(&UseMI, PHIsInCycle))
160  return false;
161  }
162 
163  return true;
164 }
165 
166 /// OptimizeBB - Remove dead PHI cycles and PHI cycles that can be replaced by
167 /// a single value.
168 bool OptimizePHIs::OptimizeBB(MachineBasicBlock &MBB) {
169  bool Changed = false;
171  MII = MBB.begin(), E = MBB.end(); MII != E; ) {
172  MachineInstr *MI = &*MII++;
173  if (!MI->isPHI())
174  break;
175 
176  // Check for single-value PHI cycles.
177  unsigned SingleValReg = 0;
178  InstrSet PHIsInCycle;
179  if (IsSingleValuePHICycle(MI, SingleValReg, PHIsInCycle) &&
180  SingleValReg != 0) {
181  unsigned OldReg = MI->getOperand(0).getReg();
182  if (!MRI->constrainRegClass(SingleValReg, MRI->getRegClass(OldReg)))
183  continue;
184 
185  // for the case SingleValReg taken from copy instr
186  MRI->clearKillFlags(SingleValReg);
187 
188  MRI->replaceRegWith(OldReg, SingleValReg);
189  MI->eraseFromParent();
190  ++NumPHICycles;
191  Changed = true;
192  continue;
193  }
194 
195  // Check for dead PHI cycles.
196  PHIsInCycle.clear();
197  if (IsDeadPHICycle(MI, PHIsInCycle)) {
198  for (InstrSetIterator PI = PHIsInCycle.begin(), PE = PHIsInCycle.end();
199  PI != PE; ++PI) {
200  MachineInstr *PhiMI = *PI;
201  if (MII == PhiMI)
202  ++MII;
203  PhiMI->eraseFromParent();
204  }
205  ++NumDeadPHICycles;
206  Changed = true;
207  }
208  }
209  return Changed;
210 }
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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
STATISTIC(NumFunctions, "Total number of functions")
void initializeOptimizePHIsPass(PassRegistry &)
bool isPHI() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
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.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
TargetInstrInfo - Interface to description of machine instruction set.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineInstrBuilder & UseMI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
bool isCopy() const
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
Definition: SmallPtrSet.h:267
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:418
INITIALIZE_PASS(OptimizePHIs, DEBUG_TYPE, "Optimize machine instruction PHIs", false, false) bool OptimizePHIs
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:286
char & OptimizePHIsID
OptimizePHIs - This pass optimizes machine instruction PHIs to take advantage of opportunities create...
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
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
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define DEBUG_TYPE
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(unsigned Reg) const