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