LLVM  9.0.0svn
HexagonMCCompound.cpp
Go to the documentation of this file.
1 //=== HexagonMCCompound.cpp - Hexagon Compound checker -------------------===//
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 //===----------------------------------------------------------------------===//
8 //
9 // This file is looks at a packet and tries to form compound insns
10 //
11 //===----------------------------------------------------------------------===//
12 
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/Support/Debug.h"
21 #include <cassert>
22 #include <cstdint>
23 
24 using namespace llvm;
25 using namespace Hexagon;
26 
27 #define DEBUG_TYPE "hexagon-mccompound"
28 
38 };
39 
40 static const unsigned tstBitOpcode[8] = {
41  J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t, J4_tstbit0_fp1_jump_nt,
42  J4_tstbit0_fp1_jump_t, J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t,
43  J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t};
44 static const unsigned cmpeqBitOpcode[8] = {
45  J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t, J4_cmpeq_fp1_jump_nt,
46  J4_cmpeq_fp1_jump_t, J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t,
47  J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t};
48 static const unsigned cmpgtBitOpcode[8] = {
49  J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t, J4_cmpgt_fp1_jump_nt,
50  J4_cmpgt_fp1_jump_t, J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t,
51  J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t};
52 static const unsigned cmpgtuBitOpcode[8] = {
53  J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t, J4_cmpgtu_fp1_jump_nt,
54  J4_cmpgtu_fp1_jump_t, J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t,
55  J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t};
56 static const unsigned cmpeqiBitOpcode[8] = {
57  J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t, J4_cmpeqi_fp1_jump_nt,
58  J4_cmpeqi_fp1_jump_t, J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t,
59  J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t};
60 static const unsigned cmpgtiBitOpcode[8] = {
61  J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t, J4_cmpgti_fp1_jump_nt,
62  J4_cmpgti_fp1_jump_t, J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t,
63  J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t};
64 static const unsigned cmpgtuiBitOpcode[8] = {
65  J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t, J4_cmpgtui_fp1_jump_nt,
66  J4_cmpgtui_fp1_jump_t, J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t,
67  J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t};
68 static const unsigned cmpeqn1BitOpcode[8] = {
69  J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t, J4_cmpeqn1_fp1_jump_nt,
70  J4_cmpeqn1_fp1_jump_t, J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t,
71  J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t};
72 static const unsigned cmpgtn1BitOpcode[8] = {
73  J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt,
74  J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t,
75  J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t,
76 };
77 
78 // enum HexagonII::CompoundGroup
79 static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
80  unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
81 
82  switch (MI.getOpcode()) {
83  default:
84  return HexagonII::HCG_None;
85  //
86  // Compound pairs.
87  // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
88  // "Rd16=#U6 ; jump #r9:2"
89  // "Rd16=Rs16 ; jump #r9:2"
90  //
91  case Hexagon::C2_cmpeq:
92  case Hexagon::C2_cmpgt:
93  case Hexagon::C2_cmpgtu:
94  if (IsExtended)
95  return false;
96  DstReg = MI.getOperand(0).getReg();
97  Src1Reg = MI.getOperand(1).getReg();
98  Src2Reg = MI.getOperand(2).getReg();
99  if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
102  return HexagonII::HCG_A;
103  break;
104  case Hexagon::C2_cmpeqi:
105  case Hexagon::C2_cmpgti:
106  case Hexagon::C2_cmpgtui:
107  if (IsExtended)
108  return false;
109  // P0 = cmp.eq(Rs,#u2)
110  DstReg = MI.getOperand(0).getReg();
111  SrcReg = MI.getOperand(1).getReg();
112  if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
114  (HexagonMCInstrInfo::inRange<5>(MI, 2) ||
115  HexagonMCInstrInfo::minConstant(MI, 2) == -1))
116  return HexagonII::HCG_A;
117  break;
118  case Hexagon::A2_tfr:
119  if (IsExtended)
120  return false;
121  // Rd = Rs
122  DstReg = MI.getOperand(0).getReg();
123  SrcReg = MI.getOperand(1).getReg();
126  return HexagonII::HCG_A;
127  break;
128  case Hexagon::A2_tfrsi:
129  if (IsExtended)
130  return false;
131  // Rd = #u6
132  DstReg = MI.getOperand(0).getReg();
133  if (HexagonMCInstrInfo::minConstant(MI, 1) <= 63 &&
134  HexagonMCInstrInfo::minConstant(MI, 1) >= 0 &&
136  return HexagonII::HCG_A;
137  break;
138  case Hexagon::S2_tstbit_i:
139  if (IsExtended)
140  return false;
141  DstReg = MI.getOperand(0).getReg();
142  Src1Reg = MI.getOperand(1).getReg();
143  if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
146  return HexagonII::HCG_A;
147  break;
148  // The fact that .new form is used pretty much guarantees
149  // that predicate register will match. Nevertheless,
150  // there could be some false positives without additional
151  // checking.
152  case Hexagon::J2_jumptnew:
153  case Hexagon::J2_jumpfnew:
154  case Hexagon::J2_jumptnewpt:
155  case Hexagon::J2_jumpfnewpt:
156  Src1Reg = MI.getOperand(0).getReg();
157  if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg)
158  return HexagonII::HCG_B;
159  break;
160  // Transfer and jump:
161  // Rd=#U6 ; jump #r9:2
162  // Rd=Rs ; jump #r9:2
163  // Do not test for jump range here.
164  case Hexagon::J2_jump:
165  case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
166  return HexagonII::HCG_C;
167  break;
168  }
169 
170  return HexagonII::HCG_None;
171 }
172 
173 /// getCompoundOp - Return the index from 0-7 into the above opcode lists.
174 static unsigned getCompoundOp(MCInst const &HMCI) {
175  const MCOperand &Predicate = HMCI.getOperand(0);
176  unsigned PredReg = Predicate.getReg();
177 
178  assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) ||
179  (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3));
180 
181  switch (HMCI.getOpcode()) {
182  default:
183  llvm_unreachable("Expected match not found.\n");
184  break;
185  case Hexagon::J2_jumpfnew:
186  return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt;
187  case Hexagon::J2_jumpfnewpt:
188  return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t;
189  case Hexagon::J2_jumptnew:
190  return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt;
191  case Hexagon::J2_jumptnewpt:
192  return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
193  }
194 }
195 
197  MCInst const &R) {
198  MCInst *CompoundInsn = nullptr;
199  unsigned compoundOpcode;
200  MCOperand Rs, Rt;
201  int64_t Value;
202  bool Success;
203 
204  switch (L.getOpcode()) {
205  default:
206  LLVM_DEBUG(dbgs() << "Possible compound ignored\n");
207  return CompoundInsn;
208 
209  case Hexagon::A2_tfrsi:
210  Rt = L.getOperand(0);
211  compoundOpcode = J4_jumpseti;
212  CompoundInsn = new (Context) MCInst;
213  CompoundInsn->setOpcode(compoundOpcode);
214 
215  CompoundInsn->addOperand(Rt);
216  CompoundInsn->addOperand(L.getOperand(1)); // Immediate
217  CompoundInsn->addOperand(R.getOperand(0)); // Jump target
218  break;
219 
220  case Hexagon::A2_tfr:
221  Rt = L.getOperand(0);
222  Rs = L.getOperand(1);
223 
224  compoundOpcode = J4_jumpsetr;
225  CompoundInsn = new (Context) MCInst;
226  CompoundInsn->setOpcode(compoundOpcode);
227  CompoundInsn->addOperand(Rt);
228  CompoundInsn->addOperand(Rs);
229  CompoundInsn->addOperand(R.getOperand(0)); // Jump target.
230 
231  break;
232 
233  case Hexagon::C2_cmpeq:
234  LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n");
235  Rs = L.getOperand(1);
236  Rt = L.getOperand(2);
237 
238  compoundOpcode = cmpeqBitOpcode[getCompoundOp(R)];
239  CompoundInsn = new (Context) MCInst;
240  CompoundInsn->setOpcode(compoundOpcode);
241  CompoundInsn->addOperand(Rs);
242  CompoundInsn->addOperand(Rt);
243  CompoundInsn->addOperand(R.getOperand(1));
244  break;
245 
246  case Hexagon::C2_cmpgt:
247  LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n");
248  Rs = L.getOperand(1);
249  Rt = L.getOperand(2);
250 
251  compoundOpcode = cmpgtBitOpcode[getCompoundOp(R)];
252  CompoundInsn = new (Context) MCInst;
253  CompoundInsn->setOpcode(compoundOpcode);
254  CompoundInsn->addOperand(Rs);
255  CompoundInsn->addOperand(Rt);
256  CompoundInsn->addOperand(R.getOperand(1));
257  break;
258 
259  case Hexagon::C2_cmpgtu:
260  LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n");
261  Rs = L.getOperand(1);
262  Rt = L.getOperand(2);
263 
264  compoundOpcode = cmpgtuBitOpcode[getCompoundOp(R)];
265  CompoundInsn = new (Context) MCInst;
266  CompoundInsn->setOpcode(compoundOpcode);
267  CompoundInsn->addOperand(Rs);
268  CompoundInsn->addOperand(Rt);
269  CompoundInsn->addOperand(R.getOperand(1));
270  break;
271 
272  case Hexagon::C2_cmpeqi:
273  LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n");
274  Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
275  (void)Success;
276  assert(Success);
277  if (Value == -1)
278  compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(R)];
279  else
280  compoundOpcode = cmpeqiBitOpcode[getCompoundOp(R)];
281 
282  Rs = L.getOperand(1);
283  CompoundInsn = new (Context) MCInst;
284  CompoundInsn->setOpcode(compoundOpcode);
285  CompoundInsn->addOperand(Rs);
286  CompoundInsn->addOperand(L.getOperand(2));
287  CompoundInsn->addOperand(R.getOperand(1));
288  break;
289 
290  case Hexagon::C2_cmpgti:
291  LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n");
292  Success = L.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
293  (void)Success;
294  assert(Success);
295  if (Value == -1)
296  compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(R)];
297  else
298  compoundOpcode = cmpgtiBitOpcode[getCompoundOp(R)];
299 
300  Rs = L.getOperand(1);
301  CompoundInsn = new (Context) MCInst;
302  CompoundInsn->setOpcode(compoundOpcode);
303  CompoundInsn->addOperand(Rs);
304  CompoundInsn->addOperand(L.getOperand(2));
305  CompoundInsn->addOperand(R.getOperand(1));
306  break;
307 
308  case Hexagon::C2_cmpgtui:
309  LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n");
310  Rs = L.getOperand(1);
311  compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(R)];
312  CompoundInsn = new (Context) MCInst;
313  CompoundInsn->setOpcode(compoundOpcode);
314  CompoundInsn->addOperand(Rs);
315  CompoundInsn->addOperand(L.getOperand(2));
316  CompoundInsn->addOperand(R.getOperand(1));
317  break;
318 
319  case Hexagon::S2_tstbit_i:
320  LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n");
321  Rs = L.getOperand(1);
322  compoundOpcode = tstBitOpcode[getCompoundOp(R)];
323  CompoundInsn = new (Context) MCInst;
324  CompoundInsn->setOpcode(compoundOpcode);
325  CompoundInsn->addOperand(Rs);
326  CompoundInsn->addOperand(R.getOperand(1));
327  break;
328  }
329 
330  return CompoundInsn;
331 }
332 
333 /// Non-Symmetrical. See if these two instructions are fit for compound pair.
334 static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
335  MCInst const &MIb, bool IsExtendedB) {
336  unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
337  unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
338  // We have two candidates - check that this is the same register
339  // we are talking about.
340  unsigned Opca = MIa.getOpcode();
341  if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C &&
342  (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi))
343  return true;
344  return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
345  (MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
346 }
347 
348 static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context,
349  MCInst &MCI) {
351  bool JExtended = false;
352  for (MCInst::iterator J =
354  J != MCI.end(); ++J) {
355  MCInst const *JumpInst = J->getInst();
356  if (HexagonMCInstrInfo::isImmext(*JumpInst)) {
357  JExtended = true;
358  continue;
359  }
360  if (HexagonMCInstrInfo::getType(MCII, *JumpInst) == HexagonII::TypeJ) {
361  // Try to pair with another insn (B)undled with jump.
362  bool BExtended = false;
363  for (MCInst::iterator B =
365  B != MCI.end(); ++B) {
366  MCInst const *Inst = B->getInst();
367  if (JumpInst == Inst)
368  continue;
369  if (HexagonMCInstrInfo::isImmext(*Inst)) {
370  BExtended = true;
371  continue;
372  }
373  LLVM_DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << ","
374  << Inst->getOpcode() << "\n");
375  if (isOrderedCompoundPair(*Inst, BExtended, *JumpInst, JExtended)) {
376  MCInst *CompoundInsn = getCompoundInsn(Context, *Inst, *JumpInst);
377  if (CompoundInsn) {
378  LLVM_DEBUG(dbgs() << "B: " << Inst->getOpcode() << ","
379  << JumpInst->getOpcode() << " Compounds to "
380  << CompoundInsn->getOpcode() << "\n");
381  J->setInst(CompoundInsn);
382  MCI.erase(B);
383  return true;
384  }
385  }
386  BExtended = false;
387  }
388  }
389  JExtended = false;
390  }
391  return false;
392 }
393 
394 /// tryCompound - Given a bundle check for compound insns when one
395 /// is found update the contents fo the bundle with the compound insn.
396 /// If a compound instruction is found then the bundle will have one
397 /// additional slot.
399  MCContext &Context, MCInst &MCI) {
401  "Non-Bundle where Bundle expected");
402 
403  // By definition a compound must have 2 insn.
404  if (MCI.size() < 2)
405  return;
406 
407  bool StartedValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
408 
409  // Create a vector, needed to keep the order of jump instructions.
410  MCInst CheckList(MCI);
411 
412  // Look for compounds until none are found, only update the bundle when
413  // a compound is found.
414  while (lookForCompound(MCII, Context, CheckList)) {
415  // Keep the original bundle around in case the shuffle fails.
416  MCInst OriginalBundle(MCI);
417 
418  // Need to update the bundle.
419  MCI = CheckList;
420 
421  if (StartedValid &&
422  !llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI)) {
423  LLVM_DEBUG(dbgs() << "Found ERROR\n");
424  MCI = OriginalBundle;
425  }
426  }
427 }
iterator end()
Definition: MCInst.h:194
iterator begin()
Definition: MCInst.h:192
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool isIntRegForSubInst(unsigned Reg)
bool isBundle(MCInst const &MCI)
static const unsigned tstBitOpcode[8]
bool isImmext(MCInst const &MCI)
void tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCI)
tryCompound - Given a bundle check for compound insns when one is found update the contents fo the bu...
void erase(iterator I)
Definition: MCInst.h:189
static const unsigned cmpeqBitOpcode[8]
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
Context object for machine code objects.
Definition: MCContext.h:64
const MCExpr * getExpr() const
Definition: MCInst.h:95
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static const unsigned cmpgtuBitOpcode[8]
static unsigned getCompoundOp(MCInst const &HMCI)
getCompoundOp - Return the index from 0-7 into the above opcode lists.
static const unsigned cmpeqiBitOpcode[8]
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
static MCInst * getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R)
SmallVectorImpl< MCOperand >::iterator iterator
Definition: MCInst.h:185
static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA, MCInst const &MIb, bool IsExtendedB)
Non-Symmetrical. See if these two instructions are fit for compound pair.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setOpcode(unsigned Op)
Definition: MCInst.h:170
size_t const bundleInstructionsOffset
static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
static const unsigned cmpgtn1BitOpcode[8]
int64_t minConstant(MCInst const &MCI, size_t Index)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static const unsigned cmpeqn1BitOpcode[8]
#define Success
size_t size() const
Definition: MCInst.h:191
Generic base class for all target subtargets.
static const unsigned cmpgtiBitOpcode[8]
static const unsigned cmpgtuiBitOpcode[8]
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const unsigned cmpgtBitOpcode[8]
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
unsigned getOpcode() const
Definition: MCInst.h:171
#define LLVM_DEBUG(X)
Definition: Debug.h:122
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI)