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