LLVM  4.0.0
HexagonGenMux.cpp
Go to the documentation of this file.
1 //===--- HexagonGenMux.cpp ------------------------------------------------===//
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 // During instruction selection, MUX instructions are generated for
11 // conditional assignments. Since such assignments often present an
12 // opportunity to predicate instructions, HexagonExpandCondsets
13 // expands MUXes into pairs of conditional transfers, and then proceeds
14 // with predication of the producers/consumers of the registers involved.
15 // This happens after exiting from the SSA form, but before the machine
16 // instruction scheduler. After the scheduler and after the register
17 // allocation there can be cases of pairs of conditional transfers
18 // resulting from a MUX where neither of them was further predicated. If
19 // these transfers are now placed far enough from the instruction defining
20 // the predicate register, they cannot use the .new form. In such cases it
21 // is better to collapse them back to a single MUX instruction.
22 
23 #define DEBUG_TYPE "hexmux"
24 
25 #include "HexagonInstrInfo.h"
26 #include "HexagonRegisterInfo.h"
27 #include "HexagonSubtarget.h"
28 #include "llvm/ADT/BitVector.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/StringRef.h"
37 #include "llvm/IR/DebugLoc.h"
38 #include "llvm/MC/MCInstrDesc.h"
39 #include "llvm/MC/MCRegisterInfo.h"
40 #include "llvm/Pass.h"
42 #include <algorithm>
43 #include <limits>
44 #include <iterator>
45 #include <utility>
46 
47 using namespace llvm;
48 
49 namespace llvm {
50 
53 
54 } // end namespace llvm
55 
56 namespace {
57 
58  class HexagonGenMux : public MachineFunctionPass {
59  public:
60  static char ID;
61 
62  HexagonGenMux() : MachineFunctionPass(ID), HII(nullptr), HRI(nullptr) {
64  }
65 
66  StringRef getPassName() const override {
67  return "Hexagon generate mux instructions";
68  }
69 
70  void getAnalysisUsage(AnalysisUsage &AU) const override {
72  }
73 
74  bool runOnMachineFunction(MachineFunction &MF) override;
75 
76  MachineFunctionProperties getRequiredProperties() const override {
79  }
80 
81  private:
82  const HexagonInstrInfo *HII;
83  const HexagonRegisterInfo *HRI;
84 
85  struct CondsetInfo {
86  unsigned PredR = 0;
87  unsigned TrueX = std::numeric_limits<unsigned>::max();
88  unsigned FalseX = std::numeric_limits<unsigned>::max();
89 
90  CondsetInfo() = default;
91  };
92 
93  struct DefUseInfo {
94  BitVector Defs, Uses;
95 
96  DefUseInfo() = default;
97  DefUseInfo(const BitVector &D, const BitVector &U) : Defs(D), Uses(U) {}
98  };
99 
100  struct MuxInfo {
102  unsigned DefR, PredR;
103  MachineOperand *SrcT, *SrcF;
104  MachineInstr *Def1, *Def2;
105 
106  MuxInfo(MachineBasicBlock::iterator It, unsigned DR, unsigned PR,
108  MachineInstr &D2)
109  : At(It), DefR(DR), PredR(PR), SrcT(TOp), SrcF(FOp), Def1(&D1),
110  Def2(&D2) {}
111  };
112 
113  typedef DenseMap<MachineInstr*,unsigned> InstrIndexMap;
114  typedef DenseMap<unsigned,DefUseInfo> DefUseInfoMap;
115  typedef SmallVector<MuxInfo,4> MuxInfoList;
116 
117  bool isRegPair(unsigned Reg) const {
118  return Hexagon::DoubleRegsRegClass.contains(Reg);
119  }
120 
121  void getSubRegs(unsigned Reg, BitVector &SRs) const;
122  void expandReg(unsigned Reg, BitVector &Set) const;
123  void getDefsUses(const MachineInstr *MI, BitVector &Defs,
124  BitVector &Uses) const;
125  void buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X,
126  DefUseInfoMap &DUM);
127  bool isCondTransfer(unsigned Opc) const;
128  unsigned getMuxOpcode(const MachineOperand &Src1,
129  const MachineOperand &Src2) const;
130  bool genMuxInBlock(MachineBasicBlock &B);
131  };
132 
133  char HexagonGenMux::ID = 0;
134 
135 } // end anonymous namespace
136 
137 INITIALIZE_PASS(HexagonGenMux, "hexagon-mux",
138  "Hexagon generate mux instructions", false, false)
139 
140 void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const {
141  for (MCSubRegIterator I(Reg, HRI); I.isValid(); ++I)
142  SRs[*I] = true;
143 }
144 
145 void HexagonGenMux::expandReg(unsigned Reg, BitVector &Set) const {
146  if (isRegPair(Reg))
147  getSubRegs(Reg, Set);
148  else
149  Set[Reg] = true;
150 }
151 
152 void HexagonGenMux::getDefsUses(const MachineInstr *MI, BitVector &Defs,
153  BitVector &Uses) const {
154  // First, get the implicit defs and uses for this instruction.
155  unsigned Opc = MI->getOpcode();
156  const MCInstrDesc &D = HII->get(Opc);
157  if (const MCPhysReg *R = D.ImplicitDefs)
158  while (*R)
159  expandReg(*R++, Defs);
160  if (const MCPhysReg *R = D.ImplicitUses)
161  while (*R)
162  expandReg(*R++, Uses);
163 
164  // Look over all operands, and collect explicit defs and uses.
165  for (const MachineOperand &MO : MI->operands()) {
166  if (!MO.isReg() || MO.isImplicit())
167  continue;
168  unsigned R = MO.getReg();
169  BitVector &Set = MO.isDef() ? Defs : Uses;
170  expandReg(R, Set);
171  }
172 }
173 
174 void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X,
175  DefUseInfoMap &DUM) {
176  unsigned Index = 0;
177  unsigned NR = HRI->getNumRegs();
178  BitVector Defs(NR), Uses(NR);
179 
180  for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) {
181  MachineInstr *MI = &*I;
182  I2X.insert(std::make_pair(MI, Index));
183  Defs.reset();
184  Uses.reset();
185  getDefsUses(MI, Defs, Uses);
186  DUM.insert(std::make_pair(Index, DefUseInfo(Defs, Uses)));
187  Index++;
188  }
189 }
190 
191 bool HexagonGenMux::isCondTransfer(unsigned Opc) const {
192  switch (Opc) {
193  case Hexagon::A2_tfrt:
194  case Hexagon::A2_tfrf:
195  case Hexagon::C2_cmoveit:
196  case Hexagon::C2_cmoveif:
197  return true;
198  }
199  return false;
200 }
201 
202 unsigned HexagonGenMux::getMuxOpcode(const MachineOperand &Src1,
203  const MachineOperand &Src2) const {
204  bool IsReg1 = Src1.isReg(), IsReg2 = Src2.isReg();
205  if (IsReg1)
206  return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir;
207  if (IsReg2)
208  return Hexagon::C2_muxri;
209 
210  // Neither is a register. The first source is extendable, but the second
211  // is not (s8).
212  if (Src2.isImm() && isInt<8>(Src2.getImm()))
213  return Hexagon::C2_muxii;
214 
215  return 0;
216 }
217 
218 bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) {
219  bool Changed = false;
220  InstrIndexMap I2X;
221  DefUseInfoMap DUM;
222  buildMaps(B, I2X, DUM);
223 
224  typedef DenseMap<unsigned,CondsetInfo> CondsetMap;
225  CondsetMap CM;
226  MuxInfoList ML;
227 
228  MachineBasicBlock::iterator NextI, End = B.end();
229  for (MachineBasicBlock::iterator I = B.begin(); I != End; I = NextI) {
230  MachineInstr *MI = &*I;
231  NextI = std::next(I);
232  unsigned Opc = MI->getOpcode();
233  if (!isCondTransfer(Opc))
234  continue;
235  unsigned DR = MI->getOperand(0).getReg();
236  if (isRegPair(DR))
237  continue;
238 
239  unsigned PR = MI->getOperand(1).getReg();
240  unsigned Idx = I2X.lookup(MI);
241  CondsetMap::iterator F = CM.find(DR);
242  bool IfTrue = HII->isPredicatedTrue(Opc);
243 
244  // If there is no record of a conditional transfer for this register,
245  // or the predicate register differs, create a new record for it.
246  if (F != CM.end() && F->second.PredR != PR) {
247  CM.erase(F);
248  F = CM.end();
249  }
250  if (F == CM.end()) {
251  auto It = CM.insert(std::make_pair(DR, CondsetInfo()));
252  F = It.first;
253  F->second.PredR = PR;
254  }
255  CondsetInfo &CI = F->second;
256  if (IfTrue)
257  CI.TrueX = Idx;
258  else
259  CI.FalseX = Idx;
260  if (CI.TrueX == std::numeric_limits<unsigned>::max() ||
261  CI.FalseX == std::numeric_limits<unsigned>::max())
262  continue;
263 
264  // There is now a complete definition of DR, i.e. we have the predicate
265  // register, the definition if-true, and definition if-false.
266 
267  // First, check if both definitions are far enough from the definition
268  // of the predicate register.
269  unsigned MinX = std::min(CI.TrueX, CI.FalseX);
270  unsigned MaxX = std::max(CI.TrueX, CI.FalseX);
271  unsigned SearchX = (MaxX > 4) ? MaxX-4 : 0;
272  bool NearDef = false;
273  for (unsigned X = SearchX; X < MaxX; ++X) {
274  const DefUseInfo &DU = DUM.lookup(X);
275  if (!DU.Defs[PR])
276  continue;
277  NearDef = true;
278  break;
279  }
280  if (NearDef)
281  continue;
282 
283  // The predicate register is not defined in the last few instructions.
284  // Check if the conversion to MUX is possible (either "up", i.e. at the
285  // place of the earlier partial definition, or "down", where the later
286  // definition is located). Examine all defs and uses between these two
287  // definitions.
288  // SR1, SR2 - source registers from the first and the second definition.
289  MachineBasicBlock::iterator It1 = B.begin(), It2 = B.begin();
290  std::advance(It1, MinX);
291  std::advance(It2, MaxX);
292  MachineInstr &Def1 = *It1, &Def2 = *It2;
293  MachineOperand *Src1 = &Def1.getOperand(2), *Src2 = &Def2.getOperand(2);
294  unsigned SR1 = Src1->isReg() ? Src1->getReg() : 0;
295  unsigned SR2 = Src2->isReg() ? Src2->getReg() : 0;
296  bool Failure = false, CanUp = true, CanDown = true;
297  for (unsigned X = MinX+1; X < MaxX; X++) {
298  const DefUseInfo &DU = DUM.lookup(X);
299  if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) {
300  Failure = true;
301  break;
302  }
303  if (CanDown && DU.Defs[SR1])
304  CanDown = false;
305  if (CanUp && DU.Defs[SR2])
306  CanUp = false;
307  }
308  if (Failure || (!CanUp && !CanDown))
309  continue;
310 
311  MachineOperand *SrcT = (MinX == CI.TrueX) ? Src1 : Src2;
312  MachineOperand *SrcF = (MinX == CI.FalseX) ? Src1 : Src2;
313  // Prefer "down", since this will move the MUX farther away from the
314  // predicate definition.
315  MachineBasicBlock::iterator At = CanDown ? Def2 : Def1;
316  ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2));
317  }
318 
319  for (unsigned I = 0, N = ML.size(); I < N; ++I) {
320  MuxInfo &MX = ML[I];
321  MachineBasicBlock &B = *MX.At->getParent();
322  DebugLoc DL = MX.At->getDebugLoc();
323  unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF);
324  if (!MxOpc)
325  continue;
326  BuildMI(B, MX.At, DL, HII->get(MxOpc), MX.DefR)
327  .addReg(MX.PredR)
328  .addOperand(*MX.SrcT)
329  .addOperand(*MX.SrcF);
330  B.erase(MX.Def1);
331  B.erase(MX.Def2);
332  Changed = true;
333  }
334 
335  return Changed;
336 }
337 
338 bool HexagonGenMux::runOnMachineFunction(MachineFunction &MF) {
339  if (skipFunction(*MF.getFunction()))
340  return false;
341  HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
342  HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
343  bool Changed = false;
344  for (auto &I : MF)
345  Changed |= genMuxInBlock(I);
346  return Changed;
347 }
348 
350  return new HexagonGenMux();
351 }
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:45
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
constexpr bool isInt< 8 >(int64_t x)
Definition: MathExtras.h:268
A debug info location.
Definition: DebugLoc.h:34
I SRs[*I]
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:301
void initializeHexagonGenMuxPass(PassRegistry &Registry)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static void advance(T &it, size_t Val)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
Reg
All possible values of the reg field in the ModR/M byte.
#define F(x, y, z)
Definition: MD5.cpp:51
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
int64_t getImm() const
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
const MCPhysReg * ImplicitDefs
Definition: MCInstrDesc.h:173
Represent the analysis usage information of a pass.
BitVector & reset()
Definition: BitVector.h:260
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
static const unsigned End
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
MCSubRegIterator enumerates all sub-registers of Reg.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:36
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
FunctionPass * createHexagonGenMux()
MachineFunctionProperties & set(Property P)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1132
Representation of each machine instruction.
Definition: MachineInstr.h:52
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
unsigned getReg() const
getReg - Returns the register number.
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
Properties which a MachineFunction may have at a given point in time.
const MCPhysReg * ImplicitUses
Definition: MCInstrDesc.h:172