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