LLVM  12.0.0git
HexagonMCChecker.cpp
Go to the documentation of this file.
1 //===----- HexagonMCChecker.cpp - Instruction bundle checking -------------===//
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 implements the checking of insns inside a bundle according to the
10 // packet constraint rules of the Hexagon ISA.
11 //
12 //===----------------------------------------------------------------------===//
13 
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrDesc.h"
23 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/Support/SourceMgr.h"
26 #include <cassert>
27 
28 using namespace llvm;
29 
30 static cl::opt<bool>
31  RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore,
32  cl::Hidden, cl::desc("Relax checks of new-value validity"));
33 
34 const HexagonMCChecker::PredSense
35  HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
36 
37 void HexagonMCChecker::init() {
38  // Initialize read-only registers set.
39  ReadOnly.insert(Hexagon::PC);
40  ReadOnly.insert(Hexagon::C9_8);
41 
42  // Figure out the loop-registers definitions.
44  Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change SA0?
45  Defs[Hexagon::LC0].insert(Unconditional);
46  }
48  Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change SA0?
49  Defs[Hexagon::LC1].insert(Unconditional);
50  }
51 
53  // Unfurl a bundle.
54  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
55  MCInst const &Inst = *I.getInst();
56  if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
57  init(*Inst.getOperand(0).getInst());
58  init(*Inst.getOperand(1).getInst());
59  } else
60  init(Inst);
61  }
62  else
63  init(MCB);
64 }
65 
66 void HexagonMCChecker::initReg(MCInst const &MCI, unsigned R, unsigned &PredReg,
67  bool &isTrue) {
68  if (HexagonMCInstrInfo::isPredicated(MCII, MCI) && isPredicateRegister(R)) {
69  // Note an used predicate register.
70  PredReg = R;
71  isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI);
72 
73  // Note use of new predicate register.
75  NewPreds.insert(PredReg);
76  } else
77  // Note register use. Super-registers are not tracked directly,
78  // but their components.
79  for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
80  SRI.isValid(); ++SRI)
81  if (!MCSubRegIterator(*SRI, &RI).isValid())
82  // Skip super-registers used indirectly.
83  Uses.insert(*SRI);
84 
86  ReversePairs.insert(R);
87 }
88 
89 void HexagonMCChecker::init(MCInst const &MCI) {
90  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
91  unsigned PredReg = Hexagon::NoRegister;
92  bool isTrue = false;
93 
94  // Get used registers.
95  for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
96  if (MCI.getOperand(i).isReg())
97  initReg(MCI, MCI.getOperand(i).getReg(), PredReg, isTrue);
98  for (unsigned i = 0; i < MCID.getNumImplicitUses(); ++i)
99  initReg(MCI, MCID.getImplicitUses()[i], PredReg, isTrue);
100 
101  // Get implicit register definitions.
102  if (const MCPhysReg *ImpDef = MCID.getImplicitDefs())
103  for (; *ImpDef; ++ImpDef) {
104  unsigned R = *ImpDef;
105 
106  if (Hexagon::R31 != R && MCID.isCall())
107  // Any register other than the LR and the PC are actually volatile ones
108  // as defined by the ABI, not modified implicitly by the call insn.
109  continue;
110  if (Hexagon::PC == R)
111  // Branches are the only insns that can change the PC,
112  // otherwise a read-only register.
113  continue;
114 
115  if (Hexagon::USR_OVF == R)
116  // Many insns change the USR implicitly, but only one or another flag.
117  // The instruction table models the USR.OVF flag, which can be
118  // implicitly modified more than once, but cannot be modified in the
119  // same packet with an instruction that modifies is explicitly. Deal
120  // with such situations individually.
121  SoftDefs.insert(R);
122  else if (isPredicateRegister(R) &&
124  // Include implicit late predicates.
125  LatePreds.insert(R);
126  else
127  Defs[R].insert(PredSense(PredReg, isTrue));
128  }
129 
130  // Figure out explicit register definitions.
131  for (unsigned i = 0; i < MCID.getNumDefs(); ++i) {
132  unsigned R = MCI.getOperand(i).getReg(), S = Hexagon::NoRegister;
133  // USR has subregisters (while C8 does not for technical reasons), so
134  // reset R to USR, since we know how to handle multiple defs of USR,
135  // taking into account its subregisters.
136  if (R == Hexagon::C8)
137  R = Hexagon::USR;
138 
140  ReversePairs.insert(R);
141 
142  // Note register definitions, direct ones as well as indirect side-effects.
143  // Super-registers are not tracked directly, but their components.
144  for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
145  SRI.isValid(); ++SRI) {
146  if (MCSubRegIterator(*SRI, &RI).isValid())
147  // Skip super-registers defined indirectly.
148  continue;
149 
150  if (R == *SRI) {
151  if (S == R)
152  // Avoid scoring the defined register multiple times.
153  continue;
154  else
155  // Note that the defined register has already been scored.
156  S = R;
157  }
158 
159  if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI)
160  // P3:0 is a special case, since multiple predicate register definitions
161  // in a packet is allowed as the equivalent of their logical "and".
162  // Only an explicit definition of P3:0 is noted as such; if a
163  // side-effect, then note as a soft definition.
164  SoftDefs.insert(*SRI);
165  else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) &&
166  isPredicateRegister(*SRI))
167  // Some insns produce predicates too late to be used in the same packet.
168  LatePreds.insert(*SRI);
169  else if (i == 0 && HexagonMCInstrInfo::getType(MCII, MCI) ==
171  // Temporary loads should be used in the same packet, but don't commit
172  // results, so it should be disregarded if another insn changes the same
173  // register.
174  // TODO: relies on the impossibility of a current and a temporary loads
175  // in the same packet.
176  TmpDefs.insert(*SRI);
177  else if (i <= 1 && HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
178  // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
179  // destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
180  Uses.insert(*SRI);
181  else
182  Defs[*SRI].insert(PredSense(PredReg, isTrue));
183  }
184  }
185 
186  // Figure out definitions of new predicate registers.
188  for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
189  if (MCI.getOperand(i).isReg()) {
190  unsigned P = MCI.getOperand(i).getReg();
191 
192  if (isPredicateRegister(P))
193  NewPreds.insert(P);
194  }
195 }
196 
198  MCSubtargetInfo const &STI, MCInst &mcb,
199  MCRegisterInfo const &ri, bool ReportErrors)
200  : Context(Context), MCB(mcb), RI(ri), MCII(MCII), STI(STI),
201  ReportErrors(ReportErrors), ReversePairs() {
202  init();
203 }
204 
206  MCSubtargetInfo const &STI,
207  bool CopyReportErrors)
208  : Context(Other.Context), MCB(Other.MCB), RI(Other.RI), MCII(Other.MCII),
209  STI(STI), ReportErrors(CopyReportErrors ? Other.ReportErrors : false),
210  ReversePairs() {
211  init();
212 }
213 
214 bool HexagonMCChecker::check(bool FullCheck) {
215  bool chkP = checkPredicates();
216  bool chkNV = checkNewValues();
217  bool chkR = checkRegisters();
218  bool chkRRO = checkRegistersReadOnly();
219  checkRegisterCurDefs();
220  bool chkS = checkSolo();
221  bool chkSh = true;
222  if (FullCheck)
223  chkSh = checkShuffle();
224  bool chkSl = true;
225  if (FullCheck)
226  chkSl = checkSlots();
227  bool chkAXOK = checkAXOK();
228  bool chkCofMax1 = checkCOFMax1();
229  bool chkHWLoop = checkHWLoop();
230  bool chkLegalVecRegPair = checkLegalVecRegPair();
231  bool chk = chkP && chkNV && chkR && chkRRO && chkS && chkSh && chkSl &&
232  chkAXOK && chkCofMax1 && chkHWLoop && chkLegalVecRegPair;
233 
234  return chk;
235 }
236 
237 static bool isDuplexAGroup(unsigned Opcode) {
238  switch (Opcode) {
239  case Hexagon::SA1_addi:
240  case Hexagon::SA1_addrx:
241  case Hexagon::SA1_addsp:
242  case Hexagon::SA1_and1:
243  case Hexagon::SA1_clrf:
244  case Hexagon::SA1_clrfnew:
245  case Hexagon::SA1_clrt:
246  case Hexagon::SA1_clrtnew:
247  case Hexagon::SA1_cmpeqi:
248  case Hexagon::SA1_combine0i:
249  case Hexagon::SA1_combine1i:
250  case Hexagon::SA1_combine2i:
251  case Hexagon::SA1_combine3i:
252  case Hexagon::SA1_combinerz:
253  case Hexagon::SA1_combinezr:
254  case Hexagon::SA1_dec:
255  case Hexagon::SA1_inc:
256  case Hexagon::SA1_seti:
257  case Hexagon::SA1_setin1:
258  case Hexagon::SA1_sxtb:
259  case Hexagon::SA1_sxth:
260  case Hexagon::SA1_tfr:
261  case Hexagon::SA1_zxtb:
262  case Hexagon::SA1_zxth:
263  return true;
264  break;
265  default:
266  return false;
267  }
268 }
269 
270 static bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
271  unsigned Result = 0;
272  unsigned Type = HexagonMCInstrInfo::getType(MCII, ID);
273  if (Type == HexagonII::TypeDUPLEX) {
274  unsigned subInst0Opcode = ID.getOperand(0).getInst()->getOpcode();
275  unsigned subInst1Opcode = ID.getOperand(1).getInst()->getOpcode();
276  Result += !isDuplexAGroup(subInst0Opcode);
277  Result += !isDuplexAGroup(subInst1Opcode);
278  } else
279  Result +=
281  Type != HexagonII::TypeALU32_ADDI && Type != HexagonII::TypeS_2op &&
282  Type != HexagonII::TypeS_3op &&
283  (Type != HexagonII::TypeALU64 || HexagonMCInstrInfo::isFloat(MCII, ID));
284  return Result != 0;
285 }
286 
287 bool HexagonMCChecker::checkAXOK() {
288  MCInst const *HasSoloAXInst = nullptr;
289  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
290  if (HexagonMCInstrInfo::isSoloAX(MCII, I)) {
291  HasSoloAXInst = &I;
292  }
293  }
294  if (!HasSoloAXInst)
295  return true;
296  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
297  if (&I != HasSoloAXInst && isNeitherAnorX(MCII, I)) {
298  reportError(
299  HasSoloAXInst->getLoc(),
300  Twine("Instruction can only be in a packet with ALU or non-FPU XTYPE "
301  "instructions"));
302  reportError(I.getLoc(),
303  Twine("Not an ALU or non-FPU XTYPE instruction"));
304  return false;
305  }
306  }
307  return true;
308 }
309 
311  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
312  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
313  if (Desc.isBranch() || Desc.isCall() || Desc.isReturn())
314  reportNote(I.getLoc(), "Branching instruction");
315  }
316 }
317 
318 bool HexagonMCChecker::checkHWLoop() {
321  return true;
322  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
323  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
324  if (Desc.isBranch() || Desc.isCall() || Desc.isReturn()) {
325  reportError(MCB.getLoc(),
326  "Branches cannot be in a packet with hardware loops");
328  return false;
329  }
330  }
331  return true;
332 }
333 
334 bool HexagonMCChecker::checkCOFMax1() {
335  SmallVector<MCInst const *, 2> BranchLocations;
336  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
337  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
338  if (Desc.isBranch() || Desc.isCall() || Desc.isReturn())
339  BranchLocations.push_back(&I);
340  }
341  for (unsigned J = 0, N = BranchLocations.size(); J < N; ++J) {
342  MCInst const &I = *BranchLocations[J];
343  if (HexagonMCInstrInfo::isCofMax1(MCII, I)) {
344  bool Relax1 = HexagonMCInstrInfo::isCofRelax1(MCII, I);
345  bool Relax2 = HexagonMCInstrInfo::isCofRelax2(MCII, I);
346  if (N > 1 && !Relax1 && !Relax2) {
347  reportError(I.getLoc(),
348  "Instruction may not be in a packet with other branches");
350  return false;
351  }
352  if (N > 1 && J == 0 && !Relax1) {
353  reportError(I.getLoc(),
354  "Instruction may not be the first branch in packet");
356  return false;
357  }
358  if (N > 1 && J == 1 && !Relax2) {
359  reportError(I.getLoc(),
360  "Instruction may not be the second branch in packet");
362  return false;
363  }
364  }
365  }
366  return true;
367 }
368 
369 bool HexagonMCChecker::checkSlots() {
370  unsigned slotsUsed = 0;
371  for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
372  MCInst const &MCI = *HMI.getInst();
374  continue;
375  if (HexagonMCInstrInfo::isDuplex(MCII, MCI))
376  slotsUsed += 2;
377  else
378  ++slotsUsed;
379  }
380 
381  if (slotsUsed > HEXAGON_PACKET_SIZE) {
382  reportError("invalid instruction packet: out of slots");
383  return false;
384  }
385  return true;
386 }
387 
388 // Check legal use of predicate registers.
389 bool HexagonMCChecker::checkPredicates() {
390  // Check for proper use of new predicate registers.
391  for (const auto &I : NewPreds) {
392  unsigned P = I;
393 
394  if (!Defs.count(P) || LatePreds.count(P) || Defs.count(Hexagon::P3_0)) {
395  // Error out if the new predicate register is not defined,
396  // or defined "late"
397  // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }").
399  return false;
400  }
401  }
402 
403  // Check for proper use of auto-anded of predicate registers.
404  for (const auto &I : LatePreds) {
405  unsigned P = I;
406 
407  if (LatePreds.count(P) > 1 || Defs.count(P)) {
408  // Error out if predicate register defined "late" multiple times or
409  // defined late and regularly defined
410  // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }".
412  return false;
413  }
414  }
415 
416  return true;
417 }
418 
419 // Check legal use of new values.
420 bool HexagonMCChecker::checkNewValues() {
421  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
422  if (!HexagonMCInstrInfo::isNewValue(MCII, I))
423  continue;
424  auto Consumer = HexagonMCInstrInfo::predicateInfo(MCII, I);
427  assert(Op.isReg());
428  auto Producer = registerProducer(Op.getReg(), Consumer);
429  if (std::get<0>(Producer) == nullptr) {
430  reportError(I.getLoc(), "New value register consumer has no producer");
431  return false;
432  }
433  if (!RelaxNVChecks) {
434  // Checks that statically prove correct new value consumption
435  if (std::get<2>(Producer).isPredicated() &&
436  (!Consumer.isPredicated() ||
438  reportNote(
439  std::get<0>(Producer)->getLoc(),
440  "Register producer is predicated and consumer is unconditional");
441  reportError(I.getLoc(),
442  "Instruction does not have a valid new register producer");
443  return false;
444  }
445  if (std::get<2>(Producer).Register != Hexagon::NoRegister &&
446  std::get<2>(Producer).Register != Consumer.Register) {
447  reportNote(std::get<0>(Producer)->getLoc(),
448  "Register producer does not use the same predicate "
449  "register as the consumer");
450  reportError(I.getLoc(),
451  "Instruction does not have a valid new register producer");
452  return false;
453  }
454  }
455  if (std::get<2>(Producer).Register == Consumer.Register &&
456  Consumer.PredicatedTrue != std::get<2>(Producer).PredicatedTrue) {
457  reportNote(
458  std::get<0>(Producer)->getLoc(),
459  "Register producer has the opposite predicate sense as consumer");
460  reportError(I.getLoc(),
461  "Instruction does not have a valid new register producer");
462  return false;
463  }
464  MCInstrDesc const &Desc =
465  HexagonMCInstrInfo::getDesc(MCII, *std::get<0>(Producer));
466  if (Desc.OpInfo[std::get<1>(Producer)].RegClass ==
467  Hexagon::DoubleRegsRegClassID) {
468  reportNote(std::get<0>(Producer)->getLoc(),
469  "Double registers cannot be new-value producers");
470  reportError(I.getLoc(),
471  "Instruction does not have a valid new register producer");
472  return false;
473  }
474  if ((Desc.mayLoad() && std::get<1>(Producer) == 1) ||
475  (Desc.mayStore() && std::get<1>(Producer) == 0)) {
476  unsigned Mode =
477  HexagonMCInstrInfo::getAddrMode(MCII, *std::get<0>(Producer));
478  StringRef ModeError;
479  if (Mode == HexagonII::AbsoluteSet)
480  ModeError = "Absolute-set";
481  if (Mode == HexagonII::PostInc)
482  ModeError = "Auto-increment";
483  if (!ModeError.empty()) {
484  reportNote(std::get<0>(Producer)->getLoc(),
485  ModeError + " registers cannot be a new-value "
486  "producer");
487  reportError(I.getLoc(),
488  "Instruction does not have a valid new register producer");
489  return false;
490  }
491  }
492  if (Branch && HexagonMCInstrInfo::isFloat(MCII, *std::get<0>(Producer))) {
493  reportNote(std::get<0>(Producer)->getLoc(),
494  "FPU instructions cannot be new-value producers for jumps");
495  reportError(I.getLoc(),
496  "Instruction does not have a valid new register producer");
497  return false;
498  }
499  }
500  return true;
501 }
502 
503 bool HexagonMCChecker::checkRegistersReadOnly() {
504  for (auto I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
505  MCInst const &Inst = *I.getInst();
506  unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
507  for (unsigned j = 0; j < Defs; ++j) {
508  MCOperand const &Operand = Inst.getOperand(j);
509  assert(Operand.isReg() && "Def is not a register");
510  unsigned Register = Operand.getReg();
511  if (ReadOnly.find(Register) != ReadOnly.end()) {
512  reportError(Inst.getLoc(), "Cannot write to read-only register `" +
513  Twine(RI.getName(Register)) + "'");
514  return false;
515  }
516  }
517  }
518  return true;
519 }
520 
521 bool HexagonMCChecker::registerUsed(unsigned Register) {
522  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB))
523  for (unsigned j = HexagonMCInstrInfo::getDesc(MCII, I).getNumDefs(),
524  n = I.getNumOperands();
525  j < n; ++j) {
526  MCOperand const &Operand = I.getOperand(j);
527  if (Operand.isReg() && Operand.getReg() == Register)
528  return true;
529  }
530  return false;
531 }
532 
533 std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
534 HexagonMCChecker::registerProducer(
535  unsigned Register, HexagonMCInstrInfo::PredicateInfo ConsumerPredicate) {
536  std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
537  WrongSense;
538  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
539  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
540  auto ProducerPredicate = HexagonMCInstrInfo::predicateInfo(MCII, I);
541  for (unsigned J = 0, N = Desc.getNumDefs(); J < N; ++J)
542  for (auto K = MCRegAliasIterator(I.getOperand(J).getReg(), &RI, true);
543  K.isValid(); ++K)
544  if (*K == Register) {
545  if (RelaxNVChecks ||
546  (ProducerPredicate.Register == ConsumerPredicate.Register &&
547  (ProducerPredicate.Register == Hexagon::NoRegister ||
548  ProducerPredicate.PredicatedTrue ==
549  ConsumerPredicate.PredicatedTrue)))
550  return std::make_tuple(&I, J, ProducerPredicate);
551  std::get<0>(WrongSense) = &I;
552  std::get<1>(WrongSense) = J;
553  std::get<2>(WrongSense) = ProducerPredicate;
554  }
555  if (Register == Hexagon::VTMP && HexagonMCInstrInfo::hasTmpDst(MCII, I))
556  return std::make_tuple(&I, 0, HexagonMCInstrInfo::PredicateInfo());
557  }
558  return WrongSense;
559 }
560 
561 void HexagonMCChecker::checkRegisterCurDefs() {
562  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
563  if (HexagonMCInstrInfo::isCVINew(MCII, I) &&
564  HexagonMCInstrInfo::getDesc(MCII, I).mayLoad()) {
565  unsigned Register = I.getOperand(0).getReg();
566  if (!registerUsed(Register))
567  reportWarning("Register `" + Twine(RI.getName(Register)) +
568  "' used with `.cur' "
569  "but not used in the same packet");
570  }
571  }
572 }
573 
574 // Check for legal register uses and definitions.
575 bool HexagonMCChecker::checkRegisters() {
576  // Check for proper register definitions.
577  for (const auto &I : Defs) {
578  unsigned R = I.first;
579 
580  if (isLoopRegister(R) && Defs.count(R) > 1 &&
583  // Error out for definitions of loop registers at the end of a loop.
584  reportError("loop-setup and some branch instructions "
585  "cannot be in the same packet");
586  return false;
587  }
588  if (SoftDefs.count(R)) {
589  // Error out for explicit changes to registers also weakly defined
590  // (e.g., "{ usr = r0; r0 = sfadd(...) }").
591  unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:.
592  unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
593  reportErrorRegisters(BadR);
594  return false;
595  }
596  if (!isPredicateRegister(R) && Defs[R].size() > 1) {
597  // Check for multiple register definitions.
598  PredSet &PM = Defs[R];
599 
600  // Check for multiple unconditional register definitions.
601  if (PM.count(Unconditional)) {
602  // Error out on an unconditional change when there are any other
603  // changes, conditional or not.
604  unsigned UsrR = Hexagon::USR;
605  unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
606  reportErrorRegisters(BadR);
607  return false;
608  }
609  // Check for multiple conditional register definitions.
610  for (const auto &J : PM) {
611  PredSense P = J;
612 
613  // Check for multiple uses of the same condition.
614  if (PM.count(P) > 1) {
615  // Error out on conditional changes based on the same predicate
616  // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }").
618  return false;
619  }
620  // Check for the use of the complementary condition.
621  P.second = !P.second;
622  if (PM.count(P) && PM.size() > 2) {
623  // Error out on conditional changes based on the same predicate
624  // multiple times
625  // (e.g., "if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =...").
627  return false;
628  }
629  }
630  }
631  }
632 
633  // Check for use of temporary definitions.
634  for (const auto &I : TmpDefs) {
635  unsigned R = I;
636 
637  if (!Uses.count(R)) {
638  // special case for vhist
639  bool vHistFound = false;
640  for (auto const &HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
641  if (HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
643  vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp
644  break;
645  }
646  }
647  // Warn on an unused temporary definition.
648  if (!vHistFound) {
649  reportWarning("register `" + Twine(RI.getName(R)) +
650  "' used with `.tmp' but not used in the same packet");
651  return true;
652  }
653  }
654  }
655 
656  return true;
657 }
658 
659 // Check for legal use of solo insns.
660 bool HexagonMCChecker::checkSolo() {
661  if (HexagonMCInstrInfo::bundleSize(MCB) > 1)
662  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
663  if (HexagonMCInstrInfo::isSolo(MCII, I)) {
664  reportError(I.getLoc(), "Instruction is marked `isSolo' and "
665  "cannot have other instructions in "
666  "the same packet");
667  return false;
668  }
669  }
670 
671  return true;
672 }
673 
674 bool HexagonMCChecker::checkShuffle() {
675  HexagonMCShuffler MCSDX(Context, ReportErrors, MCII, STI, MCB);
676  return MCSDX.check();
677 }
678 
679 void HexagonMCChecker::compoundRegisterMap(unsigned &Register) {
680  switch (Register) {
681  default:
682  break;
683  case Hexagon::R15:
684  Register = Hexagon::R23;
685  break;
686  case Hexagon::R14:
687  Register = Hexagon::R22;
688  break;
689  case Hexagon::R13:
690  Register = Hexagon::R21;
691  break;
692  case Hexagon::R12:
693  Register = Hexagon::R20;
694  break;
695  case Hexagon::R11:
696  Register = Hexagon::R19;
697  break;
698  case Hexagon::R10:
699  Register = Hexagon::R18;
700  break;
701  case Hexagon::R9:
702  Register = Hexagon::R17;
703  break;
704  case Hexagon::R8:
705  Register = Hexagon::R16;
706  break;
707  }
708 }
709 
710 void HexagonMCChecker::reportErrorRegisters(unsigned Register) {
711  reportError("register `" + Twine(RI.getName(Register)) +
712  "' modified more than once");
713 }
714 
715 void HexagonMCChecker::reportErrorNewValue(unsigned Register) {
716  reportError("register `" + Twine(RI.getName(Register)) +
717  "' used with `.new' "
718  "but not validly modified in the same packet");
719 }
720 
722  reportError(MCB.getLoc(), Msg);
723 }
724 
726  if (ReportErrors)
727  Context.reportError(Loc, Msg);
728 }
729 
731  if (ReportErrors) {
732  auto SM = Context.getSourceManager();
733  if (SM)
734  SM->PrintMessage(Loc, SourceMgr::DK_Note, Msg);
735  }
736 }
737 
739  if (ReportErrors)
740  Context.reportWarning(MCB.getLoc(), Msg);
741 }
742 
743 bool HexagonMCChecker::checkLegalVecRegPair() {
744  const bool IsPermitted = STI.getFeatureBits()[Hexagon::ArchV67];
745  const bool HasReversePairs = ReversePairs.size() != 0;
746 
747  if (!IsPermitted && HasReversePairs) {
748  for (auto R : ReversePairs)
749  reportError("register pair `" + Twine(RI.getName(R)) +
750  "' is not permitted for this architecture");
751  return false;
752  }
753  return true;
754 }
void reportErrorNewValue(unsigned Register)
unsigned getNumImplicitUses() const
Return the number of implicit uses this instruction has.
Definition: MCInstrDesc.h:554
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getAddrMode(MCInstrInfo const &MCII, MCInst const &MCI)
bool hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI)
return true if instruction has hasTmpDst attribute.
SI Whole Quad Mode
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const MCPhysReg * getImplicitUses() const
Return a list of registers that are potentially read by any instance of this machine instruction...
Definition: MCInstrDesc.h:551
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:187
MCOperand const & getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI)
bool isBundle(MCInst const &MCI)
bool isReg() const
Definition: MCInst.h:57
bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is solo, i.e., cannot be in a packet.
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Definition: SourceMgr.cpp:317
bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is newly predicated.
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:421
bool isOuterLoop(MCInst const &MCI)
bool isReturn() const
Return true if the instruction is a return.
Definition: MCInstrDesc.h:259
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn expects newly produced value.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MCInstrDesc.h:290
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
bool isCofRelax1(MCInstrInfo const &MCII, MCInst const &MCI)
bool isImmext(MCInst const &MCI)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:220
const FeatureBitset & getFeatureBits() const
bool isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI)
void reportError(SMLoc Loc, Twine const &Msg)
bool isCofRelax2(MCInstrInfo const &MCII, MCInst const &MCI)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:156
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
void reportWarning(Twine const &Msg)
Context object for machine code objects.
Definition: MCContext.h:67
PredicateInfo predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI)
const MCInst * getInst() const
Definition: MCInst.h:105
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a second value.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
#define P(N)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:434
void reportNote(SMLoc Loc, Twine const &Msg)
const MCPhysReg * getImplicitDefs() const
Return a list of registers that are potentially written by any instance of this machine instruction...
Definition: MCInstrDesc.h:573
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static bool isDuplexAGroup(unsigned Opcode)
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
static cl::opt< bool > RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value validity"))
MCRegAliasIterator enumerates all registers aliasing Reg.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:811
const SourceMgr * getSourceManager() const
Definition: MCContext.h:359
MCSubRegIterator enumerates all sub-registers of Reg.
constexpr Register(unsigned Val=0)
Definition: Register.h:23
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, const MCRegisterInfo &ri, bool ReportErrors=true)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
Promote Memory to Register
Definition: Mem2Reg.cpp:110
bool isCVINew(MCInstrInfo const &MCII, MCInst const &MCI)
void reportWarning(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:825
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition: MCInstrDesc.h:235
void reportErrorRegisters(unsigned Register)
bool isSubRegister(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA.
auto size(R &&Range, std::enable_if_t< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1473
SMLoc getLoc() const
Definition: MCInst.h:178
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:427
bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with A and X-type insns.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:80
#define I(x, y, z)
Definition: MD5.cpp:59
#define N
Generic base class for all target subtargets.
bool isCall() const
Return true if the instruction is a call.
Definition: MCInstrDesc.h:271
bool IsReverseVecRegPair(unsigned VecReg)
size_t bundleSize(MCInst const &MCI)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
bool check(bool FullCheck=true)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isInnerLoop(MCInst const &MCI)
bool isFloat(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether it is a floating-point insn.
bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI)
#define HEXAGON_PACKET_SIZE
static bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID)
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:198
Check for a valid bundle.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
Represents a location in source code.
Definition: SMLoc.h:23
unsigned getOpcode() const
Definition: MCInst.h:172
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI)
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool check()
Check that the packet is legal and enforce relative insn order.