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