LLVM  6.0.0svn
HexagonMCChecker.cpp
Go to the documentation of this file.
1 //===----- HexagonMCChecker.cpp - Instruction bundle checking -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements the checking of insns inside a bundle according to the
11 // packet constraint rules of the Hexagon ISA.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "Hexagon.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrDesc.h"
25 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include <cassert>
29 
30 using namespace llvm;
31 
32 static cl::opt<bool>
33  RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore,
34  cl::Hidden, cl::desc("Relax checks of new-value validity"));
35 
36 const HexagonMCChecker::PredSense
37  HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
38 
39 void HexagonMCChecker::init() {
40  // Initialize read-only registers set.
41  ReadOnly.insert(Hexagon::PC);
42  ReadOnly.insert(Hexagon::C9_8);
43 
44  // Figure out the loop-registers definitions.
46  Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change SA0?
47  Defs[Hexagon::LC0].insert(Unconditional);
48  }
50  Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change SA0?
51  Defs[Hexagon::LC1].insert(Unconditional);
52  }
53 
55  // Unfurl a bundle.
56  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
57  MCInst const &Inst = *I.getInst();
58  if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
59  init(*Inst.getOperand(0).getInst());
60  init(*Inst.getOperand(1).getInst());
61  } else
62  init(Inst);
63  }
64  else
65  init(MCB);
66 }
67 
68 void HexagonMCChecker::initReg(MCInst const &MCI, unsigned R, unsigned &PredReg,
69  bool &isTrue) {
70  if (HexagonMCInstrInfo::isPredicated(MCII, MCI) && isPredicateRegister(R)) {
71  // Note an used predicate register.
72  PredReg = R;
73  isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI);
74 
75  // Note use of new predicate register.
77  NewPreds.insert(PredReg);
78  } else
79  // Note register use. Super-registers are not tracked directly,
80  // but their components.
81  for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
82  SRI.isValid(); ++SRI)
83  if (!MCSubRegIterator(*SRI, &RI).isValid())
84  // Skip super-registers used indirectly.
85  Uses.insert(*SRI);
86 }
87 
88 void HexagonMCChecker::init(MCInst const &MCI) {
89  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
90  unsigned PredReg = Hexagon::NoRegister;
91  bool isTrue = false;
92 
93  // Get used registers.
94  for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
95  if (MCI.getOperand(i).isReg())
96  initReg(MCI, MCI.getOperand(i).getReg(), PredReg, isTrue);
97  for (unsigned i = 0; i < MCID.getNumImplicitUses(); ++i)
98  initReg(MCI, MCID.getImplicitUses()[i], PredReg, isTrue);
99 
100  // Get implicit register definitions.
101  if (const MCPhysReg *ImpDef = MCID.getImplicitDefs())
102  for (; *ImpDef; ++ImpDef) {
103  unsigned R = *ImpDef;
104 
105  if (Hexagon::R31 != R && MCID.isCall())
106  // Any register other than the LR and the PC are actually volatile ones
107  // as defined by the ABI, not modified implicitly by the call insn.
108  continue;
109  if (Hexagon::PC == R)
110  // Branches are the only insns that can change the PC,
111  // otherwise a read-only register.
112  continue;
113 
114  if (Hexagon::USR_OVF == R)
115  // Many insns change the USR implicitly, but only one or another flag.
116  // The instruction table models the USR.OVF flag, which can be
117  // implicitly modified more than once, but cannot be modified in the
118  // same packet with an instruction that modifies is explicitly. Deal
119  // with such situations individually.
120  SoftDefs.insert(R);
121  else if (isPredicateRegister(R) &&
123  // Include implicit late predicates.
124  LatePreds.insert(R);
125  else
126  Defs[R].insert(PredSense(PredReg, isTrue));
127  }
128 
129  // Figure out explicit register definitions.
130  for (unsigned i = 0; i < MCID.getNumDefs(); ++i) {
131  unsigned R = MCI.getOperand(i).getReg(), S = Hexagon::NoRegister;
132  // USR has subregisters (while C8 does not for technical reasons), so
133  // reset R to USR, since we know how to handle multiple defs of USR,
134  // taking into account its subregisters.
135  if (R == Hexagon::C8)
136  R = Hexagon::USR;
137 
138  // Note register definitions, direct ones as well as indirect side-effects.
139  // Super-registers are not tracked directly, but their components.
140  for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
141  SRI.isValid(); ++SRI) {
142  if (MCSubRegIterator(*SRI, &RI).isValid())
143  // Skip super-registers defined indirectly.
144  continue;
145 
146  if (R == *SRI) {
147  if (S == R)
148  // Avoid scoring the defined register multiple times.
149  continue;
150  else
151  // Note that the defined register has already been scored.
152  S = R;
153  }
154 
155  if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI)
156  // P3:0 is a special case, since multiple predicate register definitions
157  // in a packet is allowed as the equivalent of their logical "and".
158  // Only an explicit definition of P3:0 is noted as such; if a
159  // side-effect, then note as a soft definition.
160  SoftDefs.insert(*SRI);
161  else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) &&
162  isPredicateRegister(*SRI))
163  // Some insns produce predicates too late to be used in the same packet.
164  LatePreds.insert(*SRI);
165  else if (i == 0 && HexagonMCInstrInfo::getType(MCII, MCI) ==
167  // Temporary loads should be used in the same packet, but don't commit
168  // results, so it should be disregarded if another insn changes the same
169  // register.
170  // TODO: relies on the impossibility of a current and a temporary loads
171  // in the same packet.
172  TmpDefs.insert(*SRI);
173  else if (i <= 1 && HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
174  // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
175  // destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
176  Uses.insert(*SRI);
177  else
178  Defs[*SRI].insert(PredSense(PredReg, isTrue));
179  }
180  }
181 
182  // Figure out register definitions that produce new values.
183  if (HexagonMCInstrInfo::hasNewValue(MCII, MCI)) {
184  unsigned R = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg();
185 
186  if (HexagonMCInstrInfo::isCompound(MCII, MCI))
187  compoundRegisterMap(R); // Compound insns have a limited register range.
188 
189  for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
190  SRI.isValid(); ++SRI)
191  if (!MCSubRegIterator(*SRI, &RI).isValid())
192  // No super-registers defined indirectly.
193  NewDefs[*SRI].push_back(NewSense::Def(
194  PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
195  HexagonMCInstrInfo::isFloat(MCII, MCI)));
196 
197  // For fairly unique 2-dot-new producers, example:
198  // vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers.
199  if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) {
200  unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, MCI).getReg();
201 
202  bool HasSubRegs = MCSubRegIterator(R2, &RI).isValid();
203  for (MCRegAliasIterator SRI(R2, &RI, !HasSubRegs); SRI.isValid(); ++SRI)
204  if (!MCSubRegIterator(*SRI, &RI).isValid())
205  NewDefs[*SRI].push_back(NewSense::Def(
206  PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
207  HexagonMCInstrInfo::isFloat(MCII, MCI)));
208  }
209  }
210 
211  // Figure out definitions of new predicate registers.
213  for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
214  if (MCI.getOperand(i).isReg()) {
215  unsigned P = MCI.getOperand(i).getReg();
216 
217  if (isPredicateRegister(P))
218  NewPreds.insert(P);
219  }
220 
221  // Figure out uses of new values.
222  if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) {
223  unsigned N = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg();
224 
225  if (!MCSubRegIterator(N, &RI).isValid()) {
226  // Super-registers cannot use new values.
227  if (MCID.isBranch())
228  NewUses[N] = NewSense::Jmp(
230  else
231  NewUses[N] = NewSense::Use(
232  PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
233  }
234  }
235 }
236 
238  MCSubtargetInfo const &STI, MCInst &mcb,
239  MCRegisterInfo const &ri, bool ReportErrors)
240  : Context(Context), MCB(mcb), RI(ri), MCII(MCII), STI(STI),
241  ReportErrors(ReportErrors) {
242  init();
243 }
244 
245 bool HexagonMCChecker::check(bool FullCheck) {
246  bool chkB = checkBranches();
247  bool chkP = checkPredicates();
248  bool chkNV = checkNewValues();
249  bool chkR = checkRegisters();
250  bool chkRRO = checkRegistersReadOnly();
251  bool chkELB = checkEndloopBranches();
252  checkRegisterCurDefs();
253  bool chkS = checkSolo();
254  bool chkSh = true;
255  if (FullCheck)
256  chkSh = checkShuffle();
257  bool chkSl = true;
258  if (FullCheck)
259  chkSl = checkSlots();
260  bool chkAXOK = checkAXOK();
261  bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkELB && chkS &&
262  chkSh && chkSl && chkAXOK;
263 
264  return chk;
265 }
266 
267 bool HexagonMCChecker::checkEndloopBranches() {
268  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
269  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
270  if (Desc.isBranch() || Desc.isCall()) {
271  auto Inner = HexagonMCInstrInfo::isInnerLoop(MCB);
272  if (Inner || HexagonMCInstrInfo::isOuterLoop(MCB)) {
273  reportError(I.getLoc(),
274  Twine("packet marked with `:endloop") +
275  (Inner ? "0" : "1") + "' " +
276  "cannot contain instructions that modify register " + "`" +
277  Twine(RI.getName(Hexagon::PC)) + "'");
278  return false;
279  }
280  }
281  }
282  return true;
283 }
284 
285 static bool isDuplexAGroup(unsigned Opcode) {
286  switch (Opcode) {
287  case Hexagon::SA1_addi:
288  case Hexagon::SA1_addrx:
289  case Hexagon::SA1_addsp:
290  case Hexagon::SA1_and1:
291  case Hexagon::SA1_clrf:
292  case Hexagon::SA1_clrfnew:
293  case Hexagon::SA1_clrt:
294  case Hexagon::SA1_clrtnew:
295  case Hexagon::SA1_cmpeqi:
296  case Hexagon::SA1_combine0i:
297  case Hexagon::SA1_combine1i:
298  case Hexagon::SA1_combine2i:
299  case Hexagon::SA1_combine3i:
300  case Hexagon::SA1_combinerz:
301  case Hexagon::SA1_combinezr:
302  case Hexagon::SA1_dec:
303  case Hexagon::SA1_inc:
304  case Hexagon::SA1_seti:
305  case Hexagon::SA1_setin1:
306  case Hexagon::SA1_sxtb:
307  case Hexagon::SA1_sxth:
308  case Hexagon::SA1_tfr:
309  case Hexagon::SA1_zxtb:
310  case Hexagon::SA1_zxth:
311  return true;
312  break;
313  default:
314  return false;
315  }
316 }
317 
318 static bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
319  unsigned Result = 0;
320  unsigned Type = HexagonMCInstrInfo::getType(MCII, ID);
321  if (Type == HexagonII::TypeDUPLEX) {
322  unsigned subInst0Opcode = ID.getOperand(0).getInst()->getOpcode();
323  unsigned subInst1Opcode = ID.getOperand(1).getInst()->getOpcode();
324  Result += !isDuplexAGroup(subInst0Opcode);
325  Result += !isDuplexAGroup(subInst1Opcode);
326  } else
327  Result +=
329  Type != HexagonII::TypeALU32_ADDI && Type != HexagonII::TypeS_2op &&
330  Type != HexagonII::TypeS_3op &&
331  (Type != HexagonII::TypeALU64 || HexagonMCInstrInfo::isFloat(MCII, ID));
332  return Result != 0;
333 }
334 
335 bool HexagonMCChecker::checkAXOK() {
336  MCInst const *HasSoloAXInst = nullptr;
337  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
338  if (HexagonMCInstrInfo::isSoloAX(MCII, I)) {
339  HasSoloAXInst = &I;
340  }
341  }
342  if (!HasSoloAXInst)
343  return true;
344  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
345  if (&I != HasSoloAXInst && isNeitherAnorX(MCII, I)) {
346  reportError(
347  HasSoloAXInst->getLoc(),
348  Twine("Instruction can only be in a packet with ALU or non-FPU XTYPE "
349  "instructions"));
350  reportError(I.getLoc(),
351  Twine("Not an ALU or non-FPU XTYPE instruction"));
352  return false;
353  }
354  }
355  return true;
356 }
357 
358 bool HexagonMCChecker::checkSlots() {
359  unsigned slotsUsed = 0;
360  for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
361  MCInst const &MCI = *HMI.getInst();
363  continue;
364  if (HexagonMCInstrInfo::isDuplex(MCII, MCI))
365  slotsUsed += 2;
366  else
367  ++slotsUsed;
368  }
369 
370  if (slotsUsed > HEXAGON_PACKET_SIZE) {
371  reportError("invalid instruction packet: out of slots");
372  return false;
373  }
374  return true;
375 }
376 
377 // Check legal use of branches.
378 bool HexagonMCChecker::checkBranches() {
379  if (HexagonMCInstrInfo::isBundle(MCB)) {
380  bool hasConditional = false;
381  unsigned Branches = 0, Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE,
382  Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE;
383 
385  i < MCB.size(); ++i) {
386  MCInst const &MCI = *MCB.begin()[i].getInst();
387 
389  continue;
390  if (HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch() ||
391  HexagonMCInstrInfo::getDesc(MCII, MCI).isCall()) {
392  ++Branches;
393  if (HexagonMCInstrInfo::isPredicated(MCII, MCI) ||
395  hasConditional = true;
396  Conditional = i; // Record the position of the conditional branch.
397  } else {
398  Unconditional = i; // Record the position of the unconditional branch.
399  }
400  }
401  }
402 
403  if (Branches > 1)
404  if (!hasConditional || Conditional > Unconditional) {
405  // Error out if more than one unconditional branch or
406  // the conditional branch appears after the unconditional one.
407  reportError(
408  "unconditional branch cannot precede another branch in packet");
409  return false;
410  }
411  }
412 
413  return true;
414 }
415 
416 // Check legal use of predicate registers.
417 bool HexagonMCChecker::checkPredicates() {
418  // Check for proper use of new predicate registers.
419  for (const auto &I : NewPreds) {
420  unsigned P = I;
421 
422  if (!Defs.count(P) || LatePreds.count(P)) {
423  // Error out if the new predicate register is not defined,
424  // or defined "late"
425  // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }").
427  return false;
428  }
429  }
430 
431  // Check for proper use of auto-anded of predicate registers.
432  for (const auto &I : LatePreds) {
433  unsigned P = I;
434 
435  if (LatePreds.count(P) > 1 || Defs.count(P)) {
436  // Error out if predicate register defined "late" multiple times or
437  // defined late and regularly defined
438  // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }".
440  return false;
441  }
442  }
443 
444  return true;
445 }
446 
447 // Check legal use of new values.
448 bool HexagonMCChecker::checkNewValues() {
449  for (auto &I : NewUses) {
450  unsigned R = I.first;
451  NewSense &US = I.second;
452 
453  if (!hasValidNewValueDef(US, NewDefs[R])) {
455  return false;
456  }
457  }
458 
459  return true;
460 }
461 
462 bool HexagonMCChecker::checkRegistersReadOnly() {
463  for (auto I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
464  MCInst const &Inst = *I.getInst();
465  unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
466  for (unsigned j = 0; j < Defs; ++j) {
467  MCOperand const &Operand = Inst.getOperand(j);
468  assert(Operand.isReg() && "Def is not a register");
469  unsigned Register = Operand.getReg();
470  if (ReadOnly.find(Register) != ReadOnly.end()) {
471  reportError(Inst.getLoc(), "Cannot write to read-only register `" +
472  Twine(RI.getName(Register)) + "'");
473  return false;
474  }
475  }
476  }
477  return true;
478 }
479 
480 bool HexagonMCChecker::registerUsed(unsigned Register) {
481  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB))
482  for (unsigned j = HexagonMCInstrInfo::getDesc(MCII, I).getNumDefs(),
483  n = I.getNumOperands();
484  j < n; ++j) {
485  MCOperand const &Operand = I.getOperand(j);
486  if (Operand.isReg() && Operand.getReg() == Register)
487  return true;
488  }
489  return false;
490 }
491 
492 void HexagonMCChecker::checkRegisterCurDefs() {
493  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
494  if (HexagonMCInstrInfo::isCVINew(MCII, I) &&
495  HexagonMCInstrInfo::getDesc(MCII, I).mayLoad()) {
496  unsigned Register = I.getOperand(0).getReg();
497  if (!registerUsed(Register))
498  reportWarning("Register `" + Twine(RI.getName(Register)) +
499  "' used with `.cur' "
500  "but not used in the same packet");
501  }
502  }
503 }
504 
505 // Check for legal register uses and definitions.
506 bool HexagonMCChecker::checkRegisters() {
507  // Check for proper register definitions.
508  for (const auto &I : Defs) {
509  unsigned R = I.first;
510 
511  if (isLoopRegister(R) && Defs.count(R) > 1 &&
514  // Error out for definitions of loop registers at the end of a loop.
515  reportError("loop-setup and some branch instructions "
516  "cannot be in the same packet");
517  return false;
518  }
519  if (SoftDefs.count(R)) {
520  // Error out for explicit changes to registers also weakly defined
521  // (e.g., "{ usr = r0; r0 = sfadd(...) }").
522  unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:.
523  unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
524  reportErrorRegisters(BadR);
525  return false;
526  }
527  if (!isPredicateRegister(R) && Defs[R].size() > 1) {
528  // Check for multiple register definitions.
529  PredSet &PM = Defs[R];
530 
531  // Check for multiple unconditional register definitions.
532  if (PM.count(Unconditional)) {
533  // Error out on an unconditional change when there are any other
534  // changes, conditional or not.
535  unsigned UsrR = Hexagon::USR;
536  unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
537  reportErrorRegisters(BadR);
538  return false;
539  }
540  // Check for multiple conditional register definitions.
541  for (const auto &J : PM) {
542  PredSense P = J;
543 
544  // Check for multiple uses of the same condition.
545  if (PM.count(P) > 1) {
546  // Error out on conditional changes based on the same predicate
547  // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }").
549  return false;
550  }
551  // Check for the use of the complementary condition.
552  P.second = !P.second;
553  if (PM.count(P) && PM.size() > 2) {
554  // Error out on conditional changes based on the same predicate
555  // multiple times
556  // (e.g., "if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =...").
558  return false;
559  }
560  }
561  }
562  }
563 
564  // Check for use of temporary definitions.
565  for (const auto &I : TmpDefs) {
566  unsigned R = I;
567 
568  if (!Uses.count(R)) {
569  // special case for vhist
570  bool vHistFound = false;
571  for (auto const &HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
572  if (HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
574  vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp
575  break;
576  }
577  }
578  // Warn on an unused temporary definition.
579  if (!vHistFound) {
580  reportWarning("register `" + Twine(RI.getName(R)) +
581  "' used with `.tmp' but not used in the same packet");
582  return true;
583  }
584  }
585  }
586 
587  return true;
588 }
589 
590 // Check for legal use of solo insns.
591 bool HexagonMCChecker::checkSolo() {
592  if (HexagonMCInstrInfo::bundleSize(MCB) > 1)
593  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
594  if (HexagonMCInstrInfo::isSolo(MCII, I)) {
595  reportError(I.getLoc(), "Instruction is marked `isSolo' and "
596  "cannot have other instructions in "
597  "the same packet");
598  return false;
599  }
600  }
601 
602  return true;
603 }
604 
605 bool HexagonMCChecker::checkShuffle() {
606  HexagonMCShuffler MCSDX(Context, ReportErrors, MCII, STI, MCB);
607  return MCSDX.check();
608 }
609 
610 void HexagonMCChecker::compoundRegisterMap(unsigned &Register) {
611  switch (Register) {
612  default:
613  break;
614  case Hexagon::R15:
615  Register = Hexagon::R23;
616  break;
617  case Hexagon::R14:
618  Register = Hexagon::R22;
619  break;
620  case Hexagon::R13:
621  Register = Hexagon::R21;
622  break;
623  case Hexagon::R12:
624  Register = Hexagon::R20;
625  break;
626  case Hexagon::R11:
627  Register = Hexagon::R19;
628  break;
629  case Hexagon::R10:
630  Register = Hexagon::R18;
631  break;
632  case Hexagon::R9:
633  Register = Hexagon::R17;
634  break;
635  case Hexagon::R8:
636  Register = Hexagon::R16;
637  break;
638  }
639 }
640 
641 bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use,
642  const NewSenseList &Defs) const {
643  bool Strict = !RelaxNVChecks;
644 
645  for (unsigned i = 0, n = Defs.size(); i < n; ++i) {
646  const NewSense &Def = Defs[i];
647  // NVJ cannot use a new FP value [7.6.1]
648  if (Use.IsNVJ && (Def.IsFloat || Def.PredReg != 0))
649  continue;
650  // If the definition was not predicated, then it does not matter if
651  // the use is.
652  if (Def.PredReg == 0)
653  return true;
654  // With the strict checks, both the definition and the use must be
655  // predicated on the same register and condition.
656  if (Strict) {
657  if (Def.PredReg == Use.PredReg && Def.Cond == Use.Cond)
658  return true;
659  } else {
660  // With the relaxed checks, if the definition was predicated, the only
661  // detectable violation is if the use is predicated on the opposing
662  // condition, otherwise, it's ok.
663  if (Def.PredReg != Use.PredReg || Def.Cond == Use.Cond)
664  return true;
665  }
666  }
667  return false;
668 }
669 
670 void HexagonMCChecker::reportErrorRegisters(unsigned Register) {
671  reportError("register `" + Twine(RI.getName(Register)) +
672  "' modified more than once");
673 }
674 
675 void HexagonMCChecker::reportErrorNewValue(unsigned Register) {
676  reportError("register `" + Twine(RI.getName(Register)) +
677  "' used with `.new' "
678  "but not validly modified in the same packet");
679 }
680 
682  reportError(MCB.getLoc(), Msg);
683 }
684 
686  if (ReportErrors)
687  Context.reportError(Loc, Msg);
688 }
689 
691  if (ReportErrors) {
692  auto SM = Context.getSourceManager();
693  if (SM)
694  SM->PrintMessage(MCB.getLoc(), SourceMgr::DK_Warning, Msg);
695  }
696 }
void reportErrorNewValue(unsigned Register)
unsigned getNumImplicitUses() const
Return the number of implicit uses this instruction has.
Definition: MCInstrDesc.h:515
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
iterator begin()
Definition: MCInst.h:192
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
const MCPhysReg * getImplicitUses() const
Return a list of registers that are potentially read by any instance of this machine instruction...
Definition: MCInstrDesc.h:512
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:58
bool isSolo(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is solo, i.e., cannot be in a packet.
bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn is newly predicated.
#define R2(n)
bool isOuterLoop(MCInst const &MCI)
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:270
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:191
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:225
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:210
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
bool isSubRegister(unsigned RegA, unsigned RegB) const
Returns true if RegB is a sub-register of RegA.
void reportError(SMLoc Loc, Twine const &Msg)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
void reportWarning(Twine const &Msg)
Context object for machine code objects.
Definition: MCContext.h:59
const MCInst * getInst() const
Definition: MCInst.h:106
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a second value.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
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:406
bool isCompound(MCInstrInfo const &MCII, MCInst const &MCI)
const MCPhysReg * getImplicitDefs() const
Return a list of registers that are potentially written by any instance of this machine instruction...
Definition: MCInstrDesc.h:534
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static bool isDuplexAGroup(unsigned Opcode)
MCOperand const & getNewValueOperand2(MCInstrInfo const &MCII, MCInst const &MCI)
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
static cl::opt< bool > RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value validity"))
MCRegAliasIterator enumerates all registers aliasing Reg.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:570
const SourceMgr * getSourceManager() const
Definition: MCContext.h:279
MCSubRegIterator enumerates all sub-registers of Reg.
size_t const bundleInstructionsOffset
HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, const MCRegisterInfo &ri, bool ReportErrors=true)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
Promote Memory to Register
Definition: Mem2Reg.cpp:110
bool isCVINew(MCInstrInfo const &MCII, MCInst const &MCI)
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:178
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
bool isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn can be packaged only with A and X-type insns.
size_t size() const
Definition: MCInst.h:191
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
MCSubtargetInfo - Generic base class for all target subtargets.
bool isCall() const
Return true if the instruction is a call.
Definition: MCInstrDesc.h:251
#define HEXAGON_PRESHUFFLE_PACKET_SIZE
Definition: Hexagon.h:40
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:141
bool check(bool FullCheck=true)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isInnerLoop(MCInst const &MCI)
static bool isBranch(unsigned Opcode)
bool isFloat(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether it is a floating-point insn.
bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI)
static bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID)
bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a value.
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
Represents a location in source code.
Definition: SMLoc.h:24
unsigned getOpcode() const
Definition: MCInst.h:172
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI)
bool check()
Check that the packet is legal and enforce relative insn order.