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