LLVM  13.0.0git
R600InstrInfo.cpp
Go to the documentation of this file.
1 //===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===//
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 /// \file
10 /// R600 Implementation of TargetInstrInfo.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "R600InstrInfo.h"
15 #include "AMDGPU.h"
17 #include "R600Defines.h"
18 #include "R600Subtarget.h"
19 #include "llvm/ADT/SmallSet.h"
20 
21 using namespace llvm;
22 
23 #define GET_INSTRINFO_CTOR_DTOR
24 #include "R600GenDFAPacketizer.inc"
25 
26 #define GET_INSTRINFO_CTOR_DTOR
27 #define GET_INSTRMAP_INFO
28 #define GET_INSTRINFO_NAMED_OPS
29 #include "R600GenInstrInfo.inc"
30 
32  : R600GenInstrInfo(-1, -1), RI(), ST(ST) {}
33 
35  return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR;
36 }
37 
40  const DebugLoc &DL, MCRegister DestReg,
41  MCRegister SrcReg, bool KillSrc) const {
42  unsigned VectorComponents = 0;
43  if ((R600::R600_Reg128RegClass.contains(DestReg) ||
44  R600::R600_Reg128VerticalRegClass.contains(DestReg)) &&
45  (R600::R600_Reg128RegClass.contains(SrcReg) ||
46  R600::R600_Reg128VerticalRegClass.contains(SrcReg))) {
47  VectorComponents = 4;
48  } else if((R600::R600_Reg64RegClass.contains(DestReg) ||
49  R600::R600_Reg64VerticalRegClass.contains(DestReg)) &&
50  (R600::R600_Reg64RegClass.contains(SrcReg) ||
51  R600::R600_Reg64VerticalRegClass.contains(SrcReg))) {
52  VectorComponents = 2;
53  }
54 
55  if (VectorComponents > 0) {
56  for (unsigned I = 0; I < VectorComponents; I++) {
57  unsigned SubRegIndex = R600RegisterInfo::getSubRegFromChannel(I);
58  buildDefaultInstruction(MBB, MI, R600::MOV,
59  RI.getSubReg(DestReg, SubRegIndex),
60  RI.getSubReg(SrcReg, SubRegIndex))
61  .addReg(DestReg,
63  }
64  } else {
65  MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, R600::MOV,
66  DestReg, SrcReg);
67  NewMI->getOperand(getOperandIdx(*NewMI, R600::OpName::src0))
68  .setIsKill(KillSrc);
69  }
70 }
71 
72 /// \returns true if \p MBBI can be moved into a new basic.
75  for (MachineInstr::const_mop_iterator I = MBBI->operands_begin(),
76  E = MBBI->operands_end(); I != E; ++I) {
77  if (I->isReg() && !I->getReg().isVirtual() && I->isUse() &&
78  RI.isPhysRegLiveAcrossClauses(I->getReg()))
79  return false;
80  }
81  return true;
82 }
83 
84 bool R600InstrInfo::isMov(unsigned Opcode) const {
85  switch(Opcode) {
86  default:
87  return false;
88  case R600::MOV:
89  case R600::MOV_IMM_F32:
90  case R600::MOV_IMM_I32:
91  return true;
92  }
93 }
94 
95 bool R600InstrInfo::isReductionOp(unsigned Opcode) const {
96  return false;
97 }
98 
99 bool R600InstrInfo::isCubeOp(unsigned Opcode) const {
100  switch(Opcode) {
101  default: return false;
102  case R600::CUBE_r600_pseudo:
103  case R600::CUBE_r600_real:
104  case R600::CUBE_eg_pseudo:
105  case R600::CUBE_eg_real:
106  return true;
107  }
108 }
109 
110 bool R600InstrInfo::isALUInstr(unsigned Opcode) const {
111  unsigned TargetFlags = get(Opcode).TSFlags;
112 
113  return (TargetFlags & R600_InstFlag::ALU_INST);
114 }
115 
116 bool R600InstrInfo::hasInstrModifiers(unsigned Opcode) const {
117  unsigned TargetFlags = get(Opcode).TSFlags;
118 
119  return ((TargetFlags & R600_InstFlag::OP1) |
120  (TargetFlags & R600_InstFlag::OP2) |
121  (TargetFlags & R600_InstFlag::OP3));
122 }
123 
124 bool R600InstrInfo::isLDSInstr(unsigned Opcode) const {
125  unsigned TargetFlags = get(Opcode).TSFlags;
126 
127  return ((TargetFlags & R600_InstFlag::LDS_1A) |
128  (TargetFlags & R600_InstFlag::LDS_1A1D) |
129  (TargetFlags & R600_InstFlag::LDS_1A2D));
130 }
131 
132 bool R600InstrInfo::isLDSRetInstr(unsigned Opcode) const {
133  return isLDSInstr(Opcode) && getOperandIdx(Opcode, R600::OpName::dst) != -1;
134 }
135 
137  if (isALUInstr(MI.getOpcode()))
138  return true;
139  if (isVector(MI) || isCubeOp(MI.getOpcode()))
140  return true;
141  switch (MI.getOpcode()) {
142  case R600::PRED_X:
143  case R600::INTERP_PAIR_XY:
144  case R600::INTERP_PAIR_ZW:
145  case R600::INTERP_VEC_LOAD:
146  case R600::COPY:
147  case R600::DOT_4:
148  return true;
149  default:
150  return false;
151  }
152 }
153 
154 bool R600InstrInfo::isTransOnly(unsigned Opcode) const {
155  if (ST.hasCaymanISA())
156  return false;
157  return (get(Opcode).getSchedClass() == R600::Sched::TransALU);
158 }
159 
161  return isTransOnly(MI.getOpcode());
162 }
163 
164 bool R600InstrInfo::isVectorOnly(unsigned Opcode) const {
165  return (get(Opcode).getSchedClass() == R600::Sched::VecALU);
166 }
167 
169  return isVectorOnly(MI.getOpcode());
170 }
171 
172 bool R600InstrInfo::isExport(unsigned Opcode) const {
173  return (get(Opcode).TSFlags & R600_InstFlag::IS_EXPORT);
174 }
175 
176 bool R600InstrInfo::usesVertexCache(unsigned Opcode) const {
177  return ST.hasVertexCache() && IS_VTX(get(Opcode));
178 }
179 
181  const MachineFunction *MF = MI.getParent()->getParent();
182  return !AMDGPU::isCompute(MF->getFunction().getCallingConv()) &&
183  usesVertexCache(MI.getOpcode());
184 }
185 
186 bool R600InstrInfo::usesTextureCache(unsigned Opcode) const {
187  return (!ST.hasVertexCache() && IS_VTX(get(Opcode))) || IS_TEX(get(Opcode));
188 }
189 
191  const MachineFunction *MF = MI.getParent()->getParent();
192  return (AMDGPU::isCompute(MF->getFunction().getCallingConv()) &&
193  usesVertexCache(MI.getOpcode())) ||
194  usesTextureCache(MI.getOpcode());
195 }
196 
197 bool R600InstrInfo::mustBeLastInClause(unsigned Opcode) const {
198  switch (Opcode) {
199  case R600::KILLGT:
200  case R600::GROUP_BARRIER:
201  return true;
202  default:
203  return false;
204  }
205 }
206 
208  return MI.findRegisterUseOperandIdx(R600::AR_X, false, &RI) != -1;
209 }
210 
212  return MI.findRegisterDefOperandIdx(R600::AR_X, false, false, &RI) != -1;
213 }
214 
216  if (!isALUInstr(MI.getOpcode())) {
217  return false;
218  }
219  for (MachineInstr::const_mop_iterator I = MI.operands_begin(),
220  E = MI.operands_end();
221  I != E; ++I) {
222  if (!I->isReg() || !I->isUse() || I->getReg().isVirtual())
223  continue;
224 
225  if (R600::R600_LDS_SRC_REGRegClass.contains(I->getReg()))
226  return true;
227  }
228  return false;
229 }
230 
231 int R600InstrInfo::getSelIdx(unsigned Opcode, unsigned SrcIdx) const {
232  static const unsigned SrcSelTable[][2] = {
233  {R600::OpName::src0, R600::OpName::src0_sel},
234  {R600::OpName::src1, R600::OpName::src1_sel},
235  {R600::OpName::src2, R600::OpName::src2_sel},
236  {R600::OpName::src0_X, R600::OpName::src0_sel_X},
237  {R600::OpName::src0_Y, R600::OpName::src0_sel_Y},
238  {R600::OpName::src0_Z, R600::OpName::src0_sel_Z},
239  {R600::OpName::src0_W, R600::OpName::src0_sel_W},
240  {R600::OpName::src1_X, R600::OpName::src1_sel_X},
241  {R600::OpName::src1_Y, R600::OpName::src1_sel_Y},
242  {R600::OpName::src1_Z, R600::OpName::src1_sel_Z},
243  {R600::OpName::src1_W, R600::OpName::src1_sel_W}
244  };
245 
246  for (const auto &Row : SrcSelTable) {
247  if (getOperandIdx(Opcode, Row[0]) == (int)SrcIdx) {
248  return getOperandIdx(Opcode, Row[1]);
249  }
250  }
251  return -1;
252 }
253 
257 
258  if (MI.getOpcode() == R600::DOT_4) {
259  static const unsigned OpTable[8][2] = {
260  {R600::OpName::src0_X, R600::OpName::src0_sel_X},
261  {R600::OpName::src0_Y, R600::OpName::src0_sel_Y},
262  {R600::OpName::src0_Z, R600::OpName::src0_sel_Z},
263  {R600::OpName::src0_W, R600::OpName::src0_sel_W},
264  {R600::OpName::src1_X, R600::OpName::src1_sel_X},
265  {R600::OpName::src1_Y, R600::OpName::src1_sel_Y},
266  {R600::OpName::src1_Z, R600::OpName::src1_sel_Z},
267  {R600::OpName::src1_W, R600::OpName::src1_sel_W},
268  };
269 
270  for (unsigned j = 0; j < 8; j++) {
271  MachineOperand &MO =
272  MI.getOperand(getOperandIdx(MI.getOpcode(), OpTable[j][0]));
273  Register Reg = MO.getReg();
274  if (Reg == R600::ALU_CONST) {
275  MachineOperand &Sel =
276  MI.getOperand(getOperandIdx(MI.getOpcode(), OpTable[j][1]));
277  Result.push_back(std::make_pair(&MO, Sel.getImm()));
278  continue;
279  }
280 
281  }
282  return Result;
283  }
284 
285  static const unsigned OpTable[3][2] = {
286  {R600::OpName::src0, R600::OpName::src0_sel},
287  {R600::OpName::src1, R600::OpName::src1_sel},
288  {R600::OpName::src2, R600::OpName::src2_sel},
289  };
290 
291  for (unsigned j = 0; j < 3; j++) {
292  int SrcIdx = getOperandIdx(MI.getOpcode(), OpTable[j][0]);
293  if (SrcIdx < 0)
294  break;
295  MachineOperand &MO = MI.getOperand(SrcIdx);
296  Register Reg = MO.getReg();
297  if (Reg == R600::ALU_CONST) {
298  MachineOperand &Sel =
299  MI.getOperand(getOperandIdx(MI.getOpcode(), OpTable[j][1]));
300  Result.push_back(std::make_pair(&MO, Sel.getImm()));
301  continue;
302  }
303  if (Reg == R600::ALU_LITERAL_X) {
304  MachineOperand &Operand =
305  MI.getOperand(getOperandIdx(MI.getOpcode(), R600::OpName::literal));
306  if (Operand.isImm()) {
307  Result.push_back(std::make_pair(&MO, Operand.getImm()));
308  continue;
309  }
310  assert(Operand.isGlobal());
311  }
312  Result.push_back(std::make_pair(&MO, 0));
313  }
314  return Result;
315 }
316 
317 std::vector<std::pair<int, unsigned>>
318 R600InstrInfo::ExtractSrcs(MachineInstr &MI,
320  unsigned &ConstCount) const {
321  ConstCount = 0;
322  const std::pair<int, unsigned> DummyPair(-1, 0);
323  std::vector<std::pair<int, unsigned>> Result;
324  unsigned i = 0;
325  for (const auto &Src : getSrcs(MI)) {
326  ++i;
327  Register Reg = Src.first->getReg();
328  int Index = RI.getEncodingValue(Reg) & 0xff;
329  if (Reg == R600::OQAP) {
330  Result.push_back(std::make_pair(Index, 0U));
331  }
332  if (PV.find(Reg) != PV.end()) {
333  // 255 is used to tells its a PS/PV reg
334  Result.push_back(std::make_pair(255, 0U));
335  continue;
336  }
337  if (Index > 127) {
338  ConstCount++;
339  Result.push_back(DummyPair);
340  continue;
341  }
342  unsigned Chan = RI.getHWRegChan(Reg);
343  Result.push_back(std::make_pair(Index, Chan));
344  }
345  for (; i < 3; ++i)
346  Result.push_back(DummyPair);
347  return Result;
348 }
349 
350 static std::vector<std::pair<int, unsigned>>
351 Swizzle(std::vector<std::pair<int, unsigned>> Src,
353  if (Src[0] == Src[1])
354  Src[1].first = -1;
355  switch (Swz) {
357  break;
359  std::swap(Src[1], Src[2]);
360  break;
362  std::swap(Src[0], Src[1]);
363  break;
365  std::swap(Src[0], Src[1]);
366  std::swap(Src[0], Src[2]);
367  break;
369  std::swap(Src[0], Src[2]);
370  std::swap(Src[0], Src[1]);
371  break;
373  std::swap(Src[0], Src[2]);
374  break;
375  }
376  return Src;
377 }
378 
379 static unsigned getTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op) {
380  assert(Op < 3 && "Out of range swizzle index");
381  switch (Swz) {
383  unsigned Cycles[3] = { 2, 1, 0};
384  return Cycles[Op];
385  }
387  unsigned Cycles[3] = { 1, 2, 2};
388  return Cycles[Op];
389  }
391  unsigned Cycles[3] = { 2, 1, 2};
392  return Cycles[Op];
393  }
395  unsigned Cycles[3] = { 2, 2, 1};
396  return Cycles[Op];
397  }
398  default:
399  llvm_unreachable("Wrong Swizzle for Trans Slot");
400  }
401 }
402 
403 /// returns how many MIs (whose inputs are represented by IGSrcs) can be packed
404 /// in the same Instruction Group while meeting read port limitations given a
405 /// Swz swizzle sequence.
407  const std::vector<std::vector<std::pair<int, unsigned>>> &IGSrcs,
408  const std::vector<R600InstrInfo::BankSwizzle> &Swz,
409  const std::vector<std::pair<int, unsigned>> &TransSrcs,
410  R600InstrInfo::BankSwizzle TransSwz) const {
411  int Vector[4][3];
412  memset(Vector, -1, sizeof(Vector));
413  for (unsigned i = 0, e = IGSrcs.size(); i < e; i++) {
414  const std::vector<std::pair<int, unsigned>> &Srcs =
415  Swizzle(IGSrcs[i], Swz[i]);
416  for (unsigned j = 0; j < 3; j++) {
417  const std::pair<int, unsigned> &Src = Srcs[j];
418  if (Src.first < 0 || Src.first == 255)
419  continue;
420  if (Src.first == GET_REG_INDEX(RI.getEncodingValue(R600::OQAP))) {
423  // The value from output queue A (denoted by register OQAP) can
424  // only be fetched during the first cycle.
425  return false;
426  }
427  // OQAP does not count towards the normal read port restrictions
428  continue;
429  }
430  if (Vector[Src.second][j] < 0)
431  Vector[Src.second][j] = Src.first;
432  if (Vector[Src.second][j] != Src.first)
433  return i;
434  }
435  }
436  // Now check Trans Alu
437  for (unsigned i = 0, e = TransSrcs.size(); i < e; ++i) {
438  const std::pair<int, unsigned> &Src = TransSrcs[i];
439  unsigned Cycle = getTransSwizzle(TransSwz, i);
440  if (Src.first < 0)
441  continue;
442  if (Src.first == 255)
443  continue;
444  if (Vector[Src.second][Cycle] < 0)
445  Vector[Src.second][Cycle] = Src.first;
446  if (Vector[Src.second][Cycle] != Src.first)
447  return IGSrcs.size() - 1;
448  }
449  return IGSrcs.size();
450 }
451 
452 /// Given a swizzle sequence SwzCandidate and an index Idx, returns the next
453 /// (in lexicographic term) swizzle sequence assuming that all swizzles after
454 /// Idx can be skipped
455 static bool
457  std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
458  unsigned Idx) {
459  assert(Idx < SwzCandidate.size());
460  int ResetIdx = Idx;
461  while (ResetIdx > -1 && SwzCandidate[ResetIdx] == R600InstrInfo::ALU_VEC_210)
462  ResetIdx --;
463  for (unsigned i = ResetIdx + 1, e = SwzCandidate.size(); i < e; i++) {
464  SwzCandidate[i] = R600InstrInfo::ALU_VEC_012_SCL_210;
465  }
466  if (ResetIdx == -1)
467  return false;
468  int NextSwizzle = SwzCandidate[ResetIdx] + 1;
469  SwzCandidate[ResetIdx] = (R600InstrInfo::BankSwizzle)NextSwizzle;
470  return true;
471 }
472 
473 /// Enumerate all possible Swizzle sequence to find one that can meet all
474 /// read port requirements.
476  const std::vector<std::vector<std::pair<int, unsigned>>> &IGSrcs,
477  std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
478  const std::vector<std::pair<int, unsigned>> &TransSrcs,
479  R600InstrInfo::BankSwizzle TransSwz) const {
480  unsigned ValidUpTo = 0;
481  do {
482  ValidUpTo = isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz);
483  if (ValidUpTo == IGSrcs.size())
484  return true;
485  } while (NextPossibleSolution(SwzCandidate, ValidUpTo));
486  return false;
487 }
488 
489 /// Instructions in Trans slot can't read gpr at cycle 0 if they also read
490 /// a const, and can't read a gpr at cycle 1 if they read 2 const.
491 static bool
493  const std::vector<std::pair<int, unsigned>> &TransOps,
494  unsigned ConstCount) {
495  // TransALU can't read 3 constants
496  if (ConstCount > 2)
497  return false;
498  for (unsigned i = 0, e = TransOps.size(); i < e; ++i) {
499  const std::pair<int, unsigned> &Src = TransOps[i];
500  unsigned Cycle = getTransSwizzle(TransSwz, i);
501  if (Src.first < 0)
502  continue;
503  if (ConstCount > 0 && Cycle == 0)
504  return false;
505  if (ConstCount > 1 && Cycle == 1)
506  return false;
507  }
508  return true;
509 }
510 
511 bool
512 R600InstrInfo::fitsReadPortLimitations(const std::vector<MachineInstr *> &IG,
514  std::vector<BankSwizzle> &ValidSwizzle,
515  bool isLastAluTrans)
516  const {
517  //Todo : support shared src0 - src1 operand
518 
519  std::vector<std::vector<std::pair<int, unsigned>>> IGSrcs;
520  ValidSwizzle.clear();
521  unsigned ConstCount;
523  for (unsigned i = 0, e = IG.size(); i < e; ++i) {
524  IGSrcs.push_back(ExtractSrcs(*IG[i], PV, ConstCount));
525  unsigned Op = getOperandIdx(IG[i]->getOpcode(),
526  R600::OpName::bank_swizzle);
527  ValidSwizzle.push_back( (R600InstrInfo::BankSwizzle)
528  IG[i]->getOperand(Op).getImm());
529  }
530  std::vector<std::pair<int, unsigned>> TransOps;
531  if (!isLastAluTrans)
532  return FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, TransBS);
533 
534  TransOps = std::move(IGSrcs.back());
535  IGSrcs.pop_back();
536  ValidSwizzle.pop_back();
537 
538  static const R600InstrInfo::BankSwizzle TransSwz[] = {
543  };
544  for (unsigned i = 0; i < 4; i++) {
545  TransBS = TransSwz[i];
546  if (!isConstCompatible(TransBS, TransOps, ConstCount))
547  continue;
548  bool Result = FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps,
549  TransBS);
550  if (Result) {
551  ValidSwizzle.push_back(TransBS);
552  return true;
553  }
554  }
555 
556  return false;
557 }
558 
559 bool
560 R600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts)
561  const {
562  assert (Consts.size() <= 12 && "Too many operands in instructions group");
563  unsigned Pair1 = 0, Pair2 = 0;
564  for (unsigned i = 0, n = Consts.size(); i < n; ++i) {
565  unsigned ReadConstHalf = Consts[i] & 2;
566  unsigned ReadConstIndex = Consts[i] & (~3);
567  unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;
568  if (!Pair1) {
569  Pair1 = ReadHalfConst;
570  continue;
571  }
572  if (Pair1 == ReadHalfConst)
573  continue;
574  if (!Pair2) {
575  Pair2 = ReadHalfConst;
576  continue;
577  }
578  if (Pair2 != ReadHalfConst)
579  return false;
580  }
581  return true;
582 }
583 
584 bool
585 R600InstrInfo::fitsConstReadLimitations(const std::vector<MachineInstr *> &MIs)
586  const {
587  std::vector<unsigned> Consts;
588  SmallSet<int64_t, 4> Literals;
589  for (unsigned i = 0, n = MIs.size(); i < n; i++) {
590  MachineInstr &MI = *MIs[i];
591  if (!isALUInstr(MI.getOpcode()))
592  continue;
593 
594  for (const auto &Src : getSrcs(MI)) {
595  if (Src.first->getReg() == R600::ALU_LITERAL_X)
596  Literals.insert(Src.second);
597  if (Literals.size() > 4)
598  return false;
599  if (Src.first->getReg() == R600::ALU_CONST)
600  Consts.push_back(Src.second);
601  if (R600::R600_KC0RegClass.contains(Src.first->getReg()) ||
602  R600::R600_KC1RegClass.contains(Src.first->getReg())) {
603  unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff;
604  unsigned Chan = RI.getHWRegChan(Src.first->getReg());
605  Consts.push_back((Index << 2) | Chan);
606  }
607  }
608  }
609  return fitsConstReadLimitations(Consts);
610 }
611 
614  const InstrItineraryData *II = STI.getInstrItineraryData();
615  return static_cast<const R600Subtarget &>(STI).createDFAPacketizer(II);
616 }
617 
618 static bool
619 isPredicateSetter(unsigned Opcode) {
620  switch (Opcode) {
621  case R600::PRED_X:
622  return true;
623  default:
624  return false;
625  }
626 }
627 
628 static MachineInstr *
631  while (I != MBB.begin()) {
632  --I;
633  MachineInstr &MI = *I;
634  if (isPredicateSetter(MI.getOpcode()))
635  return &MI;
636  }
637 
638  return nullptr;
639 }
640 
641 static
642 bool isJump(unsigned Opcode) {
643  return Opcode == R600::JUMP || Opcode == R600::JUMP_COND;
644 }
645 
646 static bool isBranch(unsigned Opcode) {
647  return Opcode == R600::BRANCH || Opcode == R600::BRANCH_COND_i32 ||
648  Opcode == R600::BRANCH_COND_f32;
649 }
650 
652  MachineBasicBlock *&TBB,
653  MachineBasicBlock *&FBB,
655  bool AllowModify) const {
656  // Most of the following comes from the ARM implementation of analyzeBranch
657 
658  // If the block has no terminators, it just falls into the block after it.
660  if (I == MBB.end())
661  return false;
662 
663  // R600::BRANCH* instructions are only available after isel and are not
664  // handled
665  if (isBranch(I->getOpcode()))
666  return true;
667  if (!isJump(I->getOpcode())) {
668  return false;
669  }
670 
671  // Remove successive JUMP
672  while (I != MBB.begin() && std::prev(I)->getOpcode() == R600::JUMP) {
673  MachineBasicBlock::iterator PriorI = std::prev(I);
674  if (AllowModify)
675  I->removeFromParent();
676  I = PriorI;
677  }
678  MachineInstr &LastInst = *I;
679 
680  // If there is only one terminator instruction, process it.
681  unsigned LastOpc = LastInst.getOpcode();
682  if (I == MBB.begin() || !isJump((--I)->getOpcode())) {
683  if (LastOpc == R600::JUMP) {
684  TBB = LastInst.getOperand(0).getMBB();
685  return false;
686  } else if (LastOpc == R600::JUMP_COND) {
687  auto predSet = I;
688  while (!isPredicateSetter(predSet->getOpcode())) {
689  predSet = --I;
690  }
691  TBB = LastInst.getOperand(0).getMBB();
692  Cond.push_back(predSet->getOperand(1));
693  Cond.push_back(predSet->getOperand(2));
694  Cond.push_back(MachineOperand::CreateReg(R600::PRED_SEL_ONE, false));
695  return false;
696  }
697  return true; // Can't handle indirect branch.
698  }
699 
700  // Get the instruction before it if it is a terminator.
701  MachineInstr &SecondLastInst = *I;
702  unsigned SecondLastOpc = SecondLastInst.getOpcode();
703 
704  // If the block ends with a B and a Bcc, handle it.
705  if (SecondLastOpc == R600::JUMP_COND && LastOpc == R600::JUMP) {
706  auto predSet = --I;
707  while (!isPredicateSetter(predSet->getOpcode())) {
708  predSet = --I;
709  }
710  TBB = SecondLastInst.getOperand(0).getMBB();
711  FBB = LastInst.getOperand(0).getMBB();
712  Cond.push_back(predSet->getOperand(1));
713  Cond.push_back(predSet->getOperand(2));
714  Cond.push_back(MachineOperand::CreateReg(R600::PRED_SEL_ONE, false));
715  return false;
716  }
717 
718  // Otherwise, can't handle this.
719  return true;
720 }
721 
722 static
725  It != E; ++It) {
726  if (It->getOpcode() == R600::CF_ALU ||
727  It->getOpcode() == R600::CF_ALU_PUSH_BEFORE)
728  return It.getReverse();
729  }
730  return MBB.end();
731 }
732 
734  MachineBasicBlock *TBB,
735  MachineBasicBlock *FBB,
737  const DebugLoc &DL,
738  int *BytesAdded) const {
739  assert(TBB && "insertBranch must not be told to insert a fallthrough");
740  assert(!BytesAdded && "code size not handled");
741 
742  if (!FBB) {
743  if (Cond.empty()) {
744  BuildMI(&MBB, DL, get(R600::JUMP)).addMBB(TBB);
745  return 1;
746  } else {
748  assert(PredSet && "No previous predicate !");
749  addFlag(*PredSet, 0, MO_FLAG_PUSH);
750  PredSet->getOperand(2).setImm(Cond[1].getImm());
751 
752  BuildMI(&MBB, DL, get(R600::JUMP_COND))
753  .addMBB(TBB)
754  .addReg(R600::PREDICATE_BIT, RegState::Kill);
756  if (CfAlu == MBB.end())
757  return 1;
758  assert (CfAlu->getOpcode() == R600::CF_ALU);
759  CfAlu->setDesc(get(R600::CF_ALU_PUSH_BEFORE));
760  return 1;
761  }
762  } else {
764  assert(PredSet && "No previous predicate !");
765  addFlag(*PredSet, 0, MO_FLAG_PUSH);
766  PredSet->getOperand(2).setImm(Cond[1].getImm());
767  BuildMI(&MBB, DL, get(R600::JUMP_COND))
768  .addMBB(TBB)
769  .addReg(R600::PREDICATE_BIT, RegState::Kill);
770  BuildMI(&MBB, DL, get(R600::JUMP)).addMBB(FBB);
772  if (CfAlu == MBB.end())
773  return 2;
774  assert (CfAlu->getOpcode() == R600::CF_ALU);
775  CfAlu->setDesc(get(R600::CF_ALU_PUSH_BEFORE));
776  return 2;
777  }
778 }
779 
781  int *BytesRemoved) const {
782  assert(!BytesRemoved && "code size not handled");
783 
784  // Note : we leave PRED* instructions there.
785  // They may be needed when predicating instructions.
786 
788 
789  if (I == MBB.begin()) {
790  return 0;
791  }
792  --I;
793  switch (I->getOpcode()) {
794  default:
795  return 0;
796  case R600::JUMP_COND: {
798  clearFlag(*predSet, 0, MO_FLAG_PUSH);
799  I->eraseFromParent();
801  if (CfAlu == MBB.end())
802  break;
803  assert (CfAlu->getOpcode() == R600::CF_ALU_PUSH_BEFORE);
804  CfAlu->setDesc(get(R600::CF_ALU));
805  break;
806  }
807  case R600::JUMP:
808  I->eraseFromParent();
809  break;
810  }
811  I = MBB.end();
812 
813  if (I == MBB.begin()) {
814  return 1;
815  }
816  --I;
817  switch (I->getOpcode()) {
818  // FIXME: only one case??
819  default:
820  return 1;
821  case R600::JUMP_COND: {
823  clearFlag(*predSet, 0, MO_FLAG_PUSH);
824  I->eraseFromParent();
826  if (CfAlu == MBB.end())
827  break;
828  assert (CfAlu->getOpcode() == R600::CF_ALU_PUSH_BEFORE);
829  CfAlu->setDesc(get(R600::CF_ALU));
830  break;
831  }
832  case R600::JUMP:
833  I->eraseFromParent();
834  break;
835  }
836  return 2;
837 }
838 
840  int idx = MI.findFirstPredOperandIdx();
841  if (idx < 0)
842  return false;
843 
844  Register Reg = MI.getOperand(idx).getReg();
845  switch (Reg) {
846  default: return false;
847  case R600::PRED_SEL_ONE:
848  case R600::PRED_SEL_ZERO:
849  case R600::PREDICATE_BIT:
850  return true;
851  }
852 }
853 
855  // XXX: KILL* instructions can be predicated, but they must be the last
856  // instruction in a clause, so this means any instructions after them cannot
857  // be predicated. Until we have proper support for instruction clauses in the
858  // backend, we will mark KILL* instructions as unpredicable.
859 
860  if (MI.getOpcode() == R600::KILLGT) {
861  return false;
862  } else if (MI.getOpcode() == R600::CF_ALU) {
863  // If the clause start in the middle of MBB then the MBB has more
864  // than a single clause, unable to predicate several clauses.
865  if (MI.getParent()->begin() != MachineBasicBlock::const_iterator(MI))
866  return false;
867  // TODO: We don't support KC merging atm
868  return MI.getOperand(3).getImm() == 0 && MI.getOperand(4).getImm() == 0;
869  } else if (isVector(MI)) {
870  return false;
871  } else {
873  }
874 }
875 
876 bool
878  unsigned NumCycles,
879  unsigned ExtraPredCycles,
880  BranchProbability Probability) const{
881  return true;
882 }
883 
884 bool
886  unsigned NumTCycles,
887  unsigned ExtraTCycles,
888  MachineBasicBlock &FMBB,
889  unsigned NumFCycles,
890  unsigned ExtraFCycles,
891  BranchProbability Probability) const {
892  return true;
893 }
894 
895 bool
897  unsigned NumCycles,
898  BranchProbability Probability)
899  const {
900  return true;
901 }
902 
903 bool
905  MachineBasicBlock &FMBB) const {
906  return false;
907 }
908 
909 bool
911  MachineOperand &MO = Cond[1];
912  switch (MO.getImm()) {
913  case R600::PRED_SETE_INT:
914  MO.setImm(R600::PRED_SETNE_INT);
915  break;
916  case R600::PRED_SETNE_INT:
917  MO.setImm(R600::PRED_SETE_INT);
918  break;
919  case R600::PRED_SETE:
920  MO.setImm(R600::PRED_SETNE);
921  break;
922  case R600::PRED_SETNE:
923  MO.setImm(R600::PRED_SETE);
924  break;
925  default:
926  return true;
927  }
928 
929  MachineOperand &MO2 = Cond[2];
930  switch (MO2.getReg()) {
931  case R600::PRED_SEL_ZERO:
932  MO2.setReg(R600::PRED_SEL_ONE);
933  break;
934  case R600::PRED_SEL_ONE:
935  MO2.setReg(R600::PRED_SEL_ZERO);
936  break;
937  default:
938  return true;
939  }
940  return false;
941 }
942 
944  std::vector<MachineOperand> &Pred,
945  bool SkipDead) const {
946  return isPredicateSetter(MI.getOpcode());
947 }
948 
950  ArrayRef<MachineOperand> Pred) const {
951  int PIdx = MI.findFirstPredOperandIdx();
952 
953  if (MI.getOpcode() == R600::CF_ALU) {
954  MI.getOperand(8).setImm(0);
955  return true;
956  }
957 
958  if (MI.getOpcode() == R600::DOT_4) {
959  MI.getOperand(getOperandIdx(MI, R600::OpName::pred_sel_X))
960  .setReg(Pred[2].getReg());
961  MI.getOperand(getOperandIdx(MI, R600::OpName::pred_sel_Y))
962  .setReg(Pred[2].getReg());
963  MI.getOperand(getOperandIdx(MI, R600::OpName::pred_sel_Z))
964  .setReg(Pred[2].getReg());
965  MI.getOperand(getOperandIdx(MI, R600::OpName::pred_sel_W))
966  .setReg(Pred[2].getReg());
967  MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
968  MIB.addReg(R600::PREDICATE_BIT, RegState::Implicit);
969  return true;
970  }
971 
972  if (PIdx != -1) {
973  MachineOperand &PMO = MI.getOperand(PIdx);
974  PMO.setReg(Pred[2].getReg());
975  MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
976  MIB.addReg(R600::PREDICATE_BIT, RegState::Implicit);
977  return true;
978  }
979 
980  return false;
981 }
982 
983 unsigned int R600InstrInfo::getPredicationCost(const MachineInstr &) const {
984  return 2;
985 }
986 
988  const MachineInstr &,
989  unsigned *PredCost) const {
990  if (PredCost)
991  *PredCost = 2;
992  return 2;
993 }
994 
995 unsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex,
996  unsigned Channel) const {
997  assert(Channel == 0);
998  return RegIndex;
999 }
1000 
1002  switch (MI.getOpcode()) {
1003  default: {
1004  MachineBasicBlock *MBB = MI.getParent();
1005  int OffsetOpIdx =
1006  R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::addr);
1007  // addr is a custom operand with multiple MI operands, and only the
1008  // first MI operand is given a name.
1009  int RegOpIdx = OffsetOpIdx + 1;
1010  int ChanOpIdx =
1011  R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::chan);
1012  if (isRegisterLoad(MI)) {
1013  int DstOpIdx =
1014  R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::dst);
1015  unsigned RegIndex = MI.getOperand(RegOpIdx).getImm();
1016  unsigned Channel = MI.getOperand(ChanOpIdx).getImm();
1017  unsigned Address = calculateIndirectAddress(RegIndex, Channel);
1018  Register OffsetReg = MI.getOperand(OffsetOpIdx).getReg();
1019  if (OffsetReg == R600::INDIRECT_BASE_ADDR) {
1020  buildMovInstr(MBB, MI, MI.getOperand(DstOpIdx).getReg(),
1021  getIndirectAddrRegClass()->getRegister(Address));
1022  } else {
1023  buildIndirectRead(MBB, MI, MI.getOperand(DstOpIdx).getReg(), Address,
1024  OffsetReg);
1025  }
1026  } else if (isRegisterStore(MI)) {
1027  int ValOpIdx =
1029  unsigned RegIndex = MI.getOperand(RegOpIdx).getImm();
1030  unsigned Channel = MI.getOperand(ChanOpIdx).getImm();
1031  unsigned Address = calculateIndirectAddress(RegIndex, Channel);
1032  Register OffsetReg = MI.getOperand(OffsetOpIdx).getReg();
1033  if (OffsetReg == R600::INDIRECT_BASE_ADDR) {
1035  MI.getOperand(ValOpIdx).getReg());
1036  } else {
1037  buildIndirectWrite(MBB, MI, MI.getOperand(ValOpIdx).getReg(),
1038  calculateIndirectAddress(RegIndex, Channel),
1039  OffsetReg);
1040  }
1041  } else {
1042  return false;
1043  }
1044 
1045  MBB->erase(MI);
1046  return true;
1047  }
1048  case R600::R600_EXTRACT_ELT_V2:
1049  case R600::R600_EXTRACT_ELT_V4:
1050  buildIndirectRead(MI.getParent(), MI, MI.getOperand(0).getReg(),
1051  RI.getHWRegIndex(MI.getOperand(1).getReg()), // Address
1052  MI.getOperand(2).getReg(),
1053  RI.getHWRegChan(MI.getOperand(1).getReg()));
1054  break;
1055  case R600::R600_INSERT_ELT_V2:
1056  case R600::R600_INSERT_ELT_V4:
1057  buildIndirectWrite(MI.getParent(), MI, MI.getOperand(2).getReg(), // Value
1058  RI.getHWRegIndex(MI.getOperand(1).getReg()), // Address
1059  MI.getOperand(3).getReg(), // Offset
1060  RI.getHWRegChan(MI.getOperand(1).getReg())); // Channel
1061  break;
1062  }
1063  MI.eraseFromParent();
1064  return true;
1065 }
1066 
1068  const MachineFunction &MF,
1069  const R600RegisterInfo &TRI) const {
1070  const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
1071  const R600FrameLowering *TFL = ST.getFrameLowering();
1072 
1073  unsigned StackWidth = TFL->getStackWidth(MF);
1074  int End = getIndirectIndexEnd(MF);
1075 
1076  if (End == -1)
1077  return;
1078 
1079  for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) {
1080  for (unsigned Chan = 0; Chan < StackWidth; ++Chan) {
1081  unsigned Reg = R600::R600_TReg32RegClass.getRegister((4 * Index) + Chan);
1082  TRI.reserveRegisterTuples(Reserved, Reg);
1083  }
1084  }
1085 }
1086 
1088  return &R600::R600_TReg32_XRegClass;
1089 }
1090 
1091 MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
1093  unsigned ValueReg, unsigned Address,
1094  unsigned OffsetReg) const {
1095  return buildIndirectWrite(MBB, I, ValueReg, Address, OffsetReg, 0);
1096 }
1097 
1098 MachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB,
1100  unsigned ValueReg, unsigned Address,
1101  unsigned OffsetReg,
1102  unsigned AddrChan) const {
1103  unsigned AddrReg;
1104  switch (AddrChan) {
1105  default: llvm_unreachable("Invalid Channel");
1106  case 0: AddrReg = R600::R600_AddrRegClass.getRegister(Address); break;
1107  case 1: AddrReg = R600::R600_Addr_YRegClass.getRegister(Address); break;
1108  case 2: AddrReg = R600::R600_Addr_ZRegClass.getRegister(Address); break;
1109  case 3: AddrReg = R600::R600_Addr_WRegClass.getRegister(Address); break;
1110  }
1111  MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, R600::MOVA_INT_eg,
1112  R600::AR_X, OffsetReg);
1114 
1115  MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, R600::MOV,
1116  AddrReg, ValueReg)
1117  .addReg(R600::AR_X,
1119  setImmOperand(*Mov, R600::OpName::dst_rel, 1);
1120  return Mov;
1121 }
1122 
1123 MachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB,
1125  unsigned ValueReg, unsigned Address,
1126  unsigned OffsetReg) const {
1127  return buildIndirectRead(MBB, I, ValueReg, Address, OffsetReg, 0);
1128 }
1129 
1130 MachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB,
1132  unsigned ValueReg, unsigned Address,
1133  unsigned OffsetReg,
1134  unsigned AddrChan) const {
1135  unsigned AddrReg;
1136  switch (AddrChan) {
1137  default: llvm_unreachable("Invalid Channel");
1138  case 0: AddrReg = R600::R600_AddrRegClass.getRegister(Address); break;
1139  case 1: AddrReg = R600::R600_Addr_YRegClass.getRegister(Address); break;
1140  case 2: AddrReg = R600::R600_Addr_ZRegClass.getRegister(Address); break;
1141  case 3: AddrReg = R600::R600_Addr_WRegClass.getRegister(Address); break;
1142  }
1143  MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, R600::MOVA_INT_eg,
1144  R600::AR_X,
1145  OffsetReg);
1147  MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, R600::MOV,
1148  ValueReg,
1149  AddrReg)
1150  .addReg(R600::AR_X,
1152  setImmOperand(*Mov, R600::OpName::src0_rel, 1);
1153 
1154  return Mov;
1155 }
1156 
1158  const MachineRegisterInfo &MRI = MF.getRegInfo();
1159  const MachineFrameInfo &MFI = MF.getFrameInfo();
1160  int Offset = -1;
1161 
1162  if (MFI.getNumObjects() == 0) {
1163  return -1;
1164  }
1165 
1166  if (MRI.livein_empty()) {
1167  return 0;
1168  }
1169 
1170  const TargetRegisterClass *IndirectRC = getIndirectAddrRegClass();
1171  for (std::pair<unsigned, unsigned> LI : MRI.liveins()) {
1172  Register Reg = LI.first;
1173  if (Reg.isVirtual() || !IndirectRC->contains(Reg))
1174  continue;
1175 
1176  unsigned RegIndex;
1177  unsigned RegEnd;
1178  for (RegIndex = 0, RegEnd = IndirectRC->getNumRegs(); RegIndex != RegEnd;
1179  ++RegIndex) {
1180  if (IndirectRC->getRegister(RegIndex) == (unsigned)Reg)
1181  break;
1182  }
1183  Offset = std::max(Offset, (int)RegIndex);
1184  }
1185 
1186  return Offset + 1;
1187 }
1188 
1190  int Offset = 0;
1191  const MachineFrameInfo &MFI = MF.getFrameInfo();
1192 
1193  // Variable sized objects are not supported
1194  if (MFI.hasVarSizedObjects()) {
1195  return -1;
1196  }
1197 
1198  if (MFI.getNumObjects() == 0) {
1199  return -1;
1200  }
1201 
1202  const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
1203  const R600FrameLowering *TFL = ST.getFrameLowering();
1204 
1205  Register IgnoredFrameReg;
1206  Offset = TFL->getFrameIndexReference(MF, -1, IgnoredFrameReg).getFixed();
1207 
1208  return getIndirectIndexBegin(MF) + Offset;
1209 }
1210 
1212  return 115;
1213 }
1214 
1217  unsigned Opcode,
1218  unsigned DstReg,
1219  unsigned Src0Reg,
1220  unsigned Src1Reg) const {
1221  MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode),
1222  DstReg); // $dst
1223 
1224  if (Src1Reg) {
1225  MIB.addImm(0) // $update_exec_mask
1226  .addImm(0); // $update_predicate
1227  }
1228  MIB.addImm(1) // $write
1229  .addImm(0) // $omod
1230  .addImm(0) // $dst_rel
1231  .addImm(0) // $dst_clamp
1232  .addReg(Src0Reg) // $src0
1233  .addImm(0) // $src0_neg
1234  .addImm(0) // $src0_rel
1235  .addImm(0) // $src0_abs
1236  .addImm(-1); // $src0_sel
1237 
1238  if (Src1Reg) {
1239  MIB.addReg(Src1Reg) // $src1
1240  .addImm(0) // $src1_neg
1241  .addImm(0) // $src1_rel
1242  .addImm(0) // $src1_abs
1243  .addImm(-1); // $src1_sel
1244  }
1245 
1246  //XXX: The r600g finalizer expects this to be 1, once we've moved the
1247  //scheduling to the backend, we can change the default to 0.
1248  MIB.addImm(1) // $last
1249  .addReg(R600::PRED_SEL_OFF) // $pred_sel
1250  .addImm(0) // $literal
1251  .addImm(0); // $bank_swizzle
1252 
1253  return MIB;
1254 }
1255 
1256 #define OPERAND_CASE(Label) \
1257  case Label: { \
1258  static const unsigned Ops[] = \
1259  { \
1260  Label##_X, \
1261  Label##_Y, \
1262  Label##_Z, \
1263  Label##_W \
1264  }; \
1265  return Ops[Slot]; \
1266  }
1267 
1268 static unsigned getSlotedOps(unsigned Op, unsigned Slot) {
1269  switch (Op) {
1270  OPERAND_CASE(R600::OpName::update_exec_mask)
1271  OPERAND_CASE(R600::OpName::update_pred)
1273  OPERAND_CASE(R600::OpName::omod)
1274  OPERAND_CASE(R600::OpName::dst_rel)
1275  OPERAND_CASE(R600::OpName::clamp)
1276  OPERAND_CASE(R600::OpName::src0)
1277  OPERAND_CASE(R600::OpName::src0_neg)
1278  OPERAND_CASE(R600::OpName::src0_rel)
1279  OPERAND_CASE(R600::OpName::src0_abs)
1280  OPERAND_CASE(R600::OpName::src0_sel)
1281  OPERAND_CASE(R600::OpName::src1)
1282  OPERAND_CASE(R600::OpName::src1_neg)
1283  OPERAND_CASE(R600::OpName::src1_rel)
1284  OPERAND_CASE(R600::OpName::src1_abs)
1285  OPERAND_CASE(R600::OpName::src1_sel)
1286  OPERAND_CASE(R600::OpName::pred_sel)
1287  default:
1288  llvm_unreachable("Wrong Operand");
1289  }
1290 }
1291 
1292 #undef OPERAND_CASE
1293 
1295  MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg)
1296  const {
1297  assert (MI->getOpcode() == R600::DOT_4 && "Not Implemented");
1298  unsigned Opcode;
1300  Opcode = R600::DOT4_r600;
1301  else
1302  Opcode = R600::DOT4_eg;
1304  MachineOperand &Src0 = MI->getOperand(
1305  getOperandIdx(MI->getOpcode(), getSlotedOps(R600::OpName::src0, Slot)));
1306  MachineOperand &Src1 = MI->getOperand(
1307  getOperandIdx(MI->getOpcode(), getSlotedOps(R600::OpName::src1, Slot)));
1309  MBB, I, Opcode, DstReg, Src0.getReg(), Src1.getReg());
1310  static const unsigned Operands[14] = {
1311  R600::OpName::update_exec_mask,
1312  R600::OpName::update_pred,
1314  R600::OpName::omod,
1315  R600::OpName::dst_rel,
1316  R600::OpName::clamp,
1317  R600::OpName::src0_neg,
1318  R600::OpName::src0_rel,
1319  R600::OpName::src0_abs,
1320  R600::OpName::src0_sel,
1321  R600::OpName::src1_neg,
1322  R600::OpName::src1_rel,
1323  R600::OpName::src1_abs,
1324  R600::OpName::src1_sel,
1325  };
1326 
1327  MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(),
1328  getSlotedOps(R600::OpName::pred_sel, Slot)));
1329  MIB->getOperand(getOperandIdx(Opcode, R600::OpName::pred_sel))
1330  .setReg(MO.getReg());
1331 
1332  for (unsigned i = 0; i < 14; i++) {
1333  MachineOperand &MO = MI->getOperand(
1334  getOperandIdx(MI->getOpcode(), getSlotedOps(Operands[i], Slot)));
1335  assert (MO.isImm());
1336  setImmOperand(*MIB, Operands[i], MO.getImm());
1337  }
1338  MIB->getOperand(20).setImm(0);
1339  return MIB;
1340 }
1341 
1344  unsigned DstReg,
1345  uint64_t Imm) const {
1346  MachineInstr *MovImm = buildDefaultInstruction(BB, I, R600::MOV, DstReg,
1347  R600::ALU_LITERAL_X);
1348  setImmOperand(*MovImm, R600::OpName::literal, Imm);
1349  return MovImm;
1350 }
1351 
1354  unsigned DstReg, unsigned SrcReg) const {
1355  return buildDefaultInstruction(*MBB, I, R600::MOV, DstReg, SrcReg);
1356 }
1357 
1358 int R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const {
1359  return getOperandIdx(MI.getOpcode(), Op);
1360 }
1361 
1362 int R600InstrInfo::getOperandIdx(unsigned Opcode, unsigned Op) const {
1363  return R600::getNamedOperandIdx(Opcode, Op);
1364 }
1365 
1367  int64_t Imm) const {
1368  int Idx = getOperandIdx(MI, Op);
1369  assert(Idx != -1 && "Operand not supported for this instruction.");
1370  assert(MI.getOperand(Idx).isImm());
1371  MI.getOperand(Idx).setImm(Imm);
1372 }
1373 
1374 //===----------------------------------------------------------------------===//
1375 // Instruction flag getters/setters
1376 //===----------------------------------------------------------------------===//
1377 
1379  unsigned Flag) const {
1380  unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
1381  int FlagIndex = 0;
1382  if (Flag != 0) {
1383  // If we pass something other than the default value of Flag to this
1384  // function, it means we are want to set a flag on an instruction
1385  // that uses native encoding.
1386  assert(HAS_NATIVE_OPERANDS(TargetFlags));
1387  bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3;
1388  switch (Flag) {
1389  case MO_FLAG_CLAMP:
1390  FlagIndex = getOperandIdx(MI, R600::OpName::clamp);
1391  break;
1392  case MO_FLAG_MASK:
1393  FlagIndex = getOperandIdx(MI, R600::OpName::write);
1394  break;
1395  case MO_FLAG_NOT_LAST:
1396  case MO_FLAG_LAST:
1397  FlagIndex = getOperandIdx(MI, R600::OpName::last);
1398  break;
1399  case MO_FLAG_NEG:
1400  switch (SrcIdx) {
1401  case 0:
1402  FlagIndex = getOperandIdx(MI, R600::OpName::src0_neg);
1403  break;
1404  case 1:
1405  FlagIndex = getOperandIdx(MI, R600::OpName::src1_neg);
1406  break;
1407  case 2:
1408  FlagIndex = getOperandIdx(MI, R600::OpName::src2_neg);
1409  break;
1410  }
1411  break;
1412 
1413  case MO_FLAG_ABS:
1414  assert(!IsOP3 && "Cannot set absolute value modifier for OP3 "
1415  "instructions.");
1416  (void)IsOP3;
1417  switch (SrcIdx) {
1418  case 0:
1419  FlagIndex = getOperandIdx(MI, R600::OpName::src0_abs);
1420  break;
1421  case 1:
1422  FlagIndex = getOperandIdx(MI, R600::OpName::src1_abs);
1423  break;
1424  }
1425  break;
1426 
1427  default:
1428  FlagIndex = -1;
1429  break;
1430  }
1431  assert(FlagIndex != -1 && "Flag not supported for this instruction");
1432  } else {
1433  FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags);
1434  assert(FlagIndex != 0 &&
1435  "Instruction flags not supported for this instruction");
1436  }
1437 
1438  MachineOperand &FlagOp = MI.getOperand(FlagIndex);
1439  assert(FlagOp.isImm());
1440  return FlagOp;
1441 }
1442 
1443 void R600InstrInfo::addFlag(MachineInstr &MI, unsigned Operand,
1444  unsigned Flag) const {
1445  unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
1446  if (Flag == 0) {
1447  return;
1448  }
1449  if (HAS_NATIVE_OPERANDS(TargetFlags)) {
1450  MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
1451  if (Flag == MO_FLAG_NOT_LAST) {
1452  clearFlag(MI, Operand, MO_FLAG_LAST);
1453  } else if (Flag == MO_FLAG_MASK) {
1454  clearFlag(MI, Operand, Flag);
1455  } else {
1456  FlagOp.setImm(1);
1457  }
1458  } else {
1459  MachineOperand &FlagOp = getFlagOp(MI, Operand);
1460  FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand)));
1461  }
1462 }
1463 
1464 void R600InstrInfo::clearFlag(MachineInstr &MI, unsigned Operand,
1465  unsigned Flag) const {
1466  unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
1467  if (HAS_NATIVE_OPERANDS(TargetFlags)) {
1468  MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag);
1469  FlagOp.setImm(0);
1470  } else {
1471  MachineOperand &FlagOp = getFlagOp(MI);
1472  unsigned InstFlags = FlagOp.getImm();
1473  InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));
1474  FlagOp.setImm(InstFlags);
1475  }
1476 }
1477 
1479  unsigned Kind) const {
1480  switch (Kind) {
1491  }
1492 
1493  llvm_unreachable("Invalid pseudo source kind");
1494 }
i
i
Definition: README.txt:29
llvm::EngineKind::Kind
Kind
Definition: ExecutionEngine.h:524
R600_InstFlag::ALU_INST
@ ALU_INST
Definition: R600Defines.h:42
llvm::MachineFrameInfo::hasVarSizedObjects
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
Definition: MachineFrameInfo.h:351
llvm::R600InstrInfo::isALUInstr
bool isALUInstr(unsigned Opcode) const
Definition: R600InstrInfo.cpp:110
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm
Definition: AllocatorList.h:23
llvm::R600InstrInfo::setImmOperand
void setImmOperand(MachineInstr &MI, unsigned Op, int64_t Imm) const
Helper function for setting instruction flag values.
Definition: R600InstrInfo.cpp:1366
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::PseudoSourceValue::GlobalValueCallEntry
@ GlobalValueCallEntry
Definition: PseudoSourceValue.h:43
llvm::MachineOperand::CreateReg
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
Definition: MachineOperand.h:788
R600_InstFlag::OP3
@ OP3
Definition: R600Defines.h:34
llvm::R600InstrInfo::fitsReadPortLimitations
bool fitsReadPortLimitations(const std::vector< MachineInstr * > &MIs, const DenseMap< unsigned, unsigned > &PV, std::vector< BankSwizzle > &BS, bool isLastAluTrans) const
Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210 returns true and the first ...
Definition: R600InstrInfo.cpp:512
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
GET_REG_INDEX
#define GET_REG_INDEX(reg)
Definition: R600Defines.h:57
llvm::R600InstrInfo::isVectorOnly
bool isVectorOnly(unsigned Opcode) const
Definition: R600InstrInfo.cpp:164
llvm::R600InstrInfo::getIndirectIndexEnd
int getIndirectIndexEnd(const MachineFunction &MF) const
Definition: R600InstrInfo.cpp:1189
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::R600FrameLowering
Definition: R600FrameLowering.h:16
llvm::MachineOperand::setIsKill
void setIsKill(bool Val=true)
Definition: MachineOperand.h:497
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
R600_InstFlag::OP1
@ OP1
Definition: R600Defines.h:38
llvm::MachineRegisterInfo::livein_empty
bool livein_empty() const
Definition: MachineRegisterInfo.h:939
R600_InstFlag::VECTOR
@ VECTOR
Definition: R600Defines.h:35
llvm::MachineOperand::setImm
void setImm(int64_t immVal)
Definition: MachineOperand.h:652
llvm::MachineBasicBlock::findDebugLoc
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions.
Definition: MachineBasicBlock.cpp:1396
NextPossibleSolution
static bool NextPossibleSolution(std::vector< R600InstrInfo::BankSwizzle > &SwzCandidate, unsigned Idx)
Given a swizzle sequence SwzCandidate and an index Idx, returns the next (in lexicographic term) swiz...
Definition: R600InstrInfo.cpp:456
llvm::R600InstrInfo::getOperandIdx
int getOperandIdx(const MachineInstr &MI, unsigned Op) const
Get the index of Op in the MachineInstr.
Definition: R600InstrInfo.cpp:1358
llvm::R600InstrInfo::isProfitableToIfCvt
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Definition: R600InstrInfo.cpp:877
llvm::R600InstrInfo::isRegisterLoad
bool isRegisterLoad(const MachineInstr &MI) const
Definition: R600InstrInfo.h:321
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::R600RegisterInfo::getSubRegFromChannel
static unsigned getSubRegFromChannel(unsigned Channel)
Definition: R600RegisterInfo.cpp:24
R600_InstFlag::LDS_1A2D
@ LDS_1A2D
Definition: R600Defines.h:46
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::R600InstrInfo::isLegalUpTo
unsigned isLegalUpTo(const std::vector< std::vector< std::pair< int, unsigned > > > &IGSrcs, const std::vector< R600InstrInfo::BankSwizzle > &Swz, const std::vector< std::pair< int, unsigned > > &TransSrcs, R600InstrInfo::BankSwizzle TransSwz) const
returns how many MIs (whose inputs are represented by IGSrcs) can be packed in the same Instruction G...
Definition: R600InstrInfo.cpp:406
R600_InstFlag::IS_EXPORT
@ IS_EXPORT
Definition: R600Defines.h:45
llvm::R600InstrInfo::isLDSInstr
bool isLDSInstr(unsigned Opcode) const
Definition: R600InstrInfo.cpp:124
isConstCompatible
static bool isConstCompatible(R600InstrInfo::BankSwizzle TransSwz, const std::vector< std::pair< int, unsigned >> &TransOps, unsigned ConstCount)
Instructions in Trans slot can't read gpr at cycle 0 if they also read a const, and can't read a gpr ...
Definition: R600InstrInfo.cpp:492
llvm::TargetInstrInfo::isPredicable
virtual bool isPredicable(const MachineInstr &MI) const
Return true if the specified instruction can be predicated.
Definition: TargetInstrInfo.h:1471
llvm::AMDGPU::getNamedOperandIdx
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
llvm::R600InstrInfo::usesVertexCache
bool usesVertexCache(unsigned Opcode) const
Definition: R600InstrInfo.cpp:176
llvm::R600InstrInfo::canBeConsideredALU
bool canBeConsideredALU(const MachineInstr &MI) const
Definition: R600InstrInfo.cpp:136
Swizzle
static std::vector< std::pair< int, unsigned > > Swizzle(std::vector< std::pair< int, unsigned >> Src, R600InstrInfo::BankSwizzle Swz)
Definition: R600InstrInfo.cpp:351
GET_FLAG_OPERAND_IDX
#define GET_FLAG_OPERAND_IDX(Flags)
Helper for getting the operand index for the instruction flags operand.
Definition: R600Defines.h:25
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::R600InstrInfo::readsLDSSrcReg
bool readsLDSSrcReg(const MachineInstr &MI) const
Definition: R600InstrInfo.cpp:215
R600GenInstrInfo
llvm::PseudoSourceValue::JumpTable
@ JumpTable
Definition: PseudoSourceValue.h:40
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1322
llvm::R600RegisterInfo
Definition: R600RegisterInfo.h:22
llvm::R600InstrInfo::ALU_VEC_102_SCL_221
@ ALU_VEC_102_SCL_221
Definition: R600InstrInfo.h:64
llvm::R600Subtarget::hasCaymanISA
bool hasCaymanISA() const
Definition: R600Subtarget.h:114
llvm::R600InstrInfo::buildMovImm
MachineInstr * buildMovImm(MachineBasicBlock &BB, MachineBasicBlock::iterator I, unsigned DstReg, uint64_t Imm) const
Definition: R600InstrInfo.cpp:1342
llvm::TargetRegisterClass::contains
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
Definition: TargetRegisterInfo.h:91
llvm::R600InstrInfo::isExport
bool isExport(unsigned Opcode) const
Definition: R600InstrInfo.cpp:172
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
llvm::R600InstrInfo::buildMovInstr
MachineInstr * buildMovInstr(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned DstReg, unsigned SrcReg) const
Definition: R600InstrInfo.cpp:1352
IS_TEX
#define IS_TEX(desc)
Definition: R600Defines.h:60
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:147
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:534
MO_FLAG_PUSH
#define MO_FLAG_PUSH
Definition: R600Defines.h:18
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:488
llvm::R600InstrInfo::definesAddressRegister
bool definesAddressRegister(MachineInstr &MI) const
Definition: R600InstrInfo.cpp:211
llvm::R600InstrInfo::PredicateInstruction
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
Definition: R600InstrInfo.cpp:949
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::DFAPacketizer
Definition: DFAPacketizer.h:49
getOpcode
static Optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:199
llvm::R600InstrInfo::getInstrLatency
unsigned int getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
Definition: R600InstrInfo.cpp:987
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::R600InstrInfo::isVector
bool isVector(const MachineInstr &MI) const
Vector instructions are instructions that must fill all instruction slots within an instruction group...
Definition: R600InstrInfo.cpp:34
llvm::R600InstrInfo::CreateTargetScheduleState
DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const override
Definition: R600InstrInfo.cpp:613
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
MO_FLAG_MASK
#define MO_FLAG_MASK
Definition: R600Defines.h:17
llvm::MachineBasicBlock::rend
reverse_iterator rend()
Definition: MachineBasicBlock.h:278
llvm::PseudoSourceValue::FixedStack
@ FixedStack
Definition: PseudoSourceValue.h:42
llvm::R600InstrInfo::hasInstrModifiers
bool hasInstrModifiers(unsigned Opcode) const
Definition: R600InstrInfo.cpp:116
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:45
IS_VTX
#define IS_VTX(desc)
Definition: R600Defines.h:59
R600InstrInfo.h
getSlotedOps
static unsigned getSlotedOps(unsigned Op, unsigned Slot)
Definition: R600InstrInfo.cpp:1268
llvm::R600InstrInfo::expandPostRAPseudo
bool expandPostRAPseudo(MachineInstr &MI) const override
Definition: R600InstrInfo.cpp:1001
llvm::BitVector
Definition: BitVector.h:74
llvm::RegState::Implicit
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Definition: MachineInstrBuilder.h:47
NUM_MO_FLAGS
#define NUM_MO_FLAGS
Definition: R600Defines.h:21
llvm::R600InstrInfo::isReductionOp
bool isReductionOp(unsigned opcode) const
Definition: R600InstrInfo.cpp:95
MO_FLAG_CLAMP
#define MO_FLAG_CLAMP
Definition: R600Defines.h:14
llvm::PseudoSourceValue::TargetCustom
@ TargetCustom
Definition: PseudoSourceValue.h:45
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:49
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::R600InstrInfo::reserveIndirectRegisters
void reserveIndirectRegisters(BitVector &Reserved, const MachineFunction &MF, const R600RegisterInfo &TRI) const
Reserve the registers that may be accesed using indirect addressing.
Definition: R600InstrInfo.cpp:1067
llvm::R600InstrInfo::usesTextureCache
bool usesTextureCache(unsigned Opcode) const
Definition: R600InstrInfo.cpp:186
llvm::AMDGPUAS::PRIVATE_ADDRESS
@ PRIVATE_ADDRESS
Address space for private memory.
Definition: AMDGPU.h:378
Operands
mir Rename Register Operands
Definition: MIRNamerPass.cpp:78
llvm::R600InstrInfo::isProfitableToUnpredicate
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const override
Definition: R600InstrInfo.cpp:904
llvm::R600InstrInfo::getIndirectAddrRegClass
const TargetRegisterClass * getIndirectAddrRegClass() const
Definition: R600InstrInfo.cpp:1087
llvm::PseudoSourceValue::ExternalSymbolCallEntry
@ ExternalSymbolCallEntry
Definition: PseudoSourceValue.h:44
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
val
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 the input will be treated as an leaving the upper bits uninitialised For i64 store i32 val
Definition: README.txt:15
MO_FLAG_NOT_LAST
#define MO_FLAG_NOT_LAST
Definition: R600Defines.h:19
llvm::R600Subtarget
Definition: R600Subtarget.h:36
llvm::R600InstrInfo::copyPhysReg
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
Definition: R600InstrInfo.cpp:38
llvm::MachineInstrBundleIterator::getReverse
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Definition: MachineInstrBundleIterator.h:283
AMDGPUMCTargetDesc.h
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::R600InstrInfo::clearFlag
void clearFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const
Clear the specified flag on the instruction.
Definition: R600InstrInfo.cpp:1464
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:70
llvm::Function::getCallingConv
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:228
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::R600InstrInfo::FindSwizzleForVectorSlot
bool FindSwizzleForVectorSlot(const std::vector< std::vector< std::pair< int, unsigned > > > &IGSrcs, std::vector< R600InstrInfo::BankSwizzle > &SwzCandidate, const std::vector< std::pair< int, unsigned > > &TransSrcs, R600InstrInfo::BankSwizzle TransSwz) const
Enumerate all possible Swizzle sequence to find one that can meet all read port requirements.
Definition: R600InstrInfo.cpp:475
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:58
llvm::DenseMap< unsigned, unsigned >
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::R600Subtarget::getGeneration
Generation getGeneration() const
Definition: R600Subtarget.h:82
llvm::MachineRegisterInfo::liveins
ArrayRef< std::pair< MCRegister, Register > > liveins() const
Definition: MachineRegisterInfo.h:941
HAS_NATIVE_OPERANDS
#define HAS_NATIVE_OPERANDS(Flags)
Definition: R600Defines.h:50
llvm::HighlightColor::Address
@ Address
llvm::PseudoSourceValue::ConstantPool
@ ConstantPool
Definition: PseudoSourceValue.h:41
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::R600RegisterInfo::getHWRegIndex
unsigned getHWRegIndex(unsigned Reg) const
Definition: R600RegisterInfo.cpp:83
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:958
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:571
FindLastAluClause
static MachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB)
Definition: R600InstrInfo.cpp:723
MO_FLAG_NEG
#define MO_FLAG_NEG
Definition: R600Defines.h:15
MO_FLAG_ABS
#define MO_FLAG_ABS
Definition: R600Defines.h:16
llvm::AMDGPUSubtarget::R700
@ R700
Definition: AMDGPUSubtarget.h:34
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:98
isBranch
static bool isBranch(unsigned Opcode)
Definition: R600InstrInfo.cpp:646
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:357
getTransSwizzle
static unsigned getTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op)
Definition: R600InstrInfo.cpp:379
llvm::R600InstrInfo::isCubeOp
bool isCubeOp(unsigned opcode) const
Definition: R600InstrInfo.cpp:99
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::R600InstrInfo::getFlagOp
MachineOperand & getFlagOp(MachineInstr &MI, unsigned SrcIdx=0, unsigned Flag=0) const
Definition: R600InstrInfo.cpp:1378
llvm::MachineOperand::getMBB
MachineBasicBlock * getMBB() const
Definition: MachineOperand.h:549
R600_InstFlag::OP2
@ OP2
Definition: R600Defines.h:39
Cond
SmallVector< MachineOperand, 4 > Cond
Definition: BasicBlockSections.cpp:167
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition: MachineBasicBlock.h:272
llvm::R600InstrInfo::getAddressSpaceForPseudoSourceKind
unsigned getAddressSpaceForPseudoSourceKind(unsigned Kind) const override
Definition: R600InstrInfo.cpp:1478
AMDGPU.h
llvm::MachineBasicBlock::getLastNonDebugInstr
iterator getLastNonDebugInstr(bool SkipPseudoOp=false)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Definition: MachineBasicBlock.cpp:264
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:478
llvm::R600InstrInfo::isLDSRetInstr
bool isLDSRetInstr(unsigned Opcode) const
Definition: R600InstrInfo.cpp:132
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::R600InstrInfo::insertBranch
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Definition: R600InstrInfo.cpp:733
llvm::AMDGPU::isCompute
bool isCompute(CallingConv::ID cc)
Definition: AMDGPUBaseInfo.cpp:1332
llvm::BranchProbability
Definition: BranchProbability.h:30
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
OPERAND_CASE
#define OPERAND_CASE(Label)
Definition: R600InstrInfo.cpp:1256
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:180
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:59
llvm::R600InstrInfo::ALU_VEC_012_SCL_210
@ ALU_VEC_012_SCL_210
Definition: R600InstrInfo.h:61
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::R600InstrInfo::mustBeLastInClause
bool mustBeLastInClause(unsigned Opcode) const
Definition: R600InstrInfo.cpp:197
llvm::R600InstrInfo::isPredicable
bool isPredicable(const MachineInstr &MI) const override
Definition: R600InstrInfo.cpp:854
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::PseudoSourceValue::GOT
@ GOT
Definition: PseudoSourceValue.h:39
llvm::R600InstrInfo::isTransOnly
bool isTransOnly(unsigned Opcode) const
Definition: R600InstrInfo.cpp:154
j
return j(j<< 16)
llvm::TargetRegisterClass::getNumRegs
unsigned getNumRegs() const
Return the number of registers in this class.
Definition: TargetRegisterInfo.h:77
llvm::R600InstrInfo::calculateIndirectAddress
unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const
Calculate the "Indirect Address" for the given RegIndex and Channel.
Definition: R600InstrInfo.cpp:995
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:521
R600_InstFlag::LDS_1A1D
@ LDS_1A1D
Definition: R600Defines.h:44
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:83
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::TargetRegisterClass::getRegister
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
Definition: TargetRegisterInfo.h:85
llvm::R600InstrInfo::R600InstrInfo
R600InstrInfo(const R600Subtarget &)
Definition: R600InstrInfo.cpp:31
llvm::R600InstrInfo::fitsConstReadLimitations
bool fitsConstReadLimitations(const std::vector< MachineInstr * > &) const
An instruction group can only access 2 channel pair (either [XY] or [ZW]) from KCache bank on R700+.
Definition: R600InstrInfo.cpp:585
llvm::R600InstrInfo::getSrcs
SmallVector< std::pair< MachineOperand *, int64_t >, 3 > getSrcs(MachineInstr &MI) const
Definition: R600InstrInfo.cpp:255
llvm::R600InstrInfo::addFlag
void addFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const
Add one of the MO_FLAG* flags to the specified Operand.
Definition: R600InstrInfo.cpp:1443
llvm::R600InstrInfo::isProfitableToDupForIfCvt
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
Definition: R600InstrInfo.cpp:896
llvm::R600InstrInfo::BankSwizzle
BankSwizzle
Definition: R600InstrInfo.h:60
R600Subtarget.h
llvm::R600InstrInfo::isPredicated
bool isPredicated(const MachineInstr &MI) const override
Definition: R600InstrInfo.cpp:839
llvm::R600InstrInfo::analyzeBranch
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Definition: R600InstrInfo.cpp:651
llvm::PseudoSourceValue::Stack
@ Stack
Definition: PseudoSourceValue.h:38
llvm::R600InstrInfo::reverseBranchCondition
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Definition: R600InstrInfo.cpp:910
llvm::R600InstrInfo::buildSlotOfVectorInstruction
MachineInstr * buildSlotOfVectorInstruction(MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg) const
Definition: R600InstrInfo.cpp:1294
R600_InstFlag::LDS_1A
@ LDS_1A
Definition: R600Defines.h:43
llvm::R600RegisterInfo::isPhysRegLiveAcrossClauses
bool isPhysRegLiveAcrossClauses(Register Reg) const
Definition: R600RegisterInfo.cpp:95
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:320
llvm::MachineFrameInfo::getNumObjects
unsigned getNumObjects() const
Return the number of objects.
Definition: MachineFrameInfo.h:397
Vector
So we should use XX3Form_Rcr to implement instrinsic Convert DP outs ins xscvdpsp No builtin are required Round &Convert QP DP(dword[1] is set to zero) No builtin are required Round to Quad Precision because you need to assign rounding mode in instruction Provide builtin(set f128:$vT,(int_ppc_vsx_xsrqpi f128:$vB))(set f128 yields< n x< ty > >< result > yields< ty >< result > No builtin are required Load Store Vector
Definition: README_P9.txt:497
llvm::R600InstrInfo::getMaxAlusPerClause
unsigned getMaxAlusPerClause() const
Definition: R600InstrInfo.cpp:1211
llvm::R600InstrInfo::isRegisterStore
bool isRegisterStore(const MachineInstr &MI) const
Definition: R600InstrInfo.h:317
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
llvm::R600InstrInfo::getSelIdx
int getSelIdx(unsigned Opcode, unsigned SrcIdx) const
Definition: R600InstrInfo.cpp:231
findFirstPredicateSetterFrom
static MachineInstr * findFirstPredicateSetterFrom(MachineBasicBlock &MBB, MachineBasicBlock::iterator I)
Definition: R600InstrInfo.cpp:629
R600Defines.h
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
llvm::TargetSubtargetInfo::getInstrItineraryData
virtual const InstrItineraryData * getInstrItineraryData() const
getInstrItineraryData - Returns instruction itinerary data for the target or specific subtarget.
Definition: TargetSubtargetInfo.h:132
llvm::SmallSet::size
size_type size() const
Definition: SmallSet.h:159
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:329
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:55
isJump
static bool isJump(unsigned Opcode)
Definition: R600InstrInfo.cpp:642
llvm::PseudoProbeAttributes::Reserved
@ Reserved
llvm::R600InstrInfo::isLegalToSplitMBBAt
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override
Definition: R600InstrInfo.cpp:73
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
llvm::R600InstrInfo::ALU_VEC_201
@ ALU_VEC_201
Definition: R600InstrInfo.h:65
llvm::R600InstrInfo::buildDefaultInstruction
MachineInstrBuilder buildDefaultInstruction(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opcode, unsigned DstReg, unsigned Src0Reg, unsigned Src1Reg=0) const
buildDefaultInstruction - This function returns a MachineInstr with all the instruction modifiers ini...
Definition: R600InstrInfo.cpp:1215
llvm::R600InstrInfo::ClobbersPredicate
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
Definition: R600InstrInfo.cpp:943
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
isPredicateSetter
static bool isPredicateSetter(unsigned Opcode)
Definition: R600InstrInfo.cpp:619
llvm::R600InstrInfo::ALU_VEC_120_SCL_212
@ ALU_VEC_120_SCL_212
Definition: R600InstrInfo.h:63
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AMDGPUAS::CONSTANT_ADDRESS
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
Definition: AMDGPU.h:376
llvm::R600InstrInfo::removeBranch
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemvoed=nullptr) const override
Definition: R600InstrInfo.cpp:780
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::R600InstrInfo::getPredicationCost
unsigned int getPredicationCost(const MachineInstr &) const override
Definition: R600InstrInfo.cpp:983
llvm::R600RegisterInfo::getHWRegChan
unsigned getHWRegChan(unsigned reg) const
get the HW encoding for a register's channel.
Definition: R600RegisterInfo.cpp:79
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
MO_FLAG_LAST
#define MO_FLAG_LAST
Definition: R600Defines.h:20
llvm::R600InstrInfo::getIndirectIndexBegin
int getIndirectIndexBegin(const MachineFunction &MF) const
Definition: R600InstrInfo.cpp:1157
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::R600InstrInfo::ALU_VEC_210
@ ALU_VEC_210
Definition: R600InstrInfo.h:66
llvm::R600InstrInfo::isMov
bool isMov(unsigned Opcode) const
Definition: R600InstrInfo.cpp:84
llvm::R600InstrInfo::usesAddressRegister
bool usesAddressRegister(MachineInstr &MI) const
Definition: R600InstrInfo.cpp:207
llvm::InstrItineraryData
Itinerary data supplied by a subtarget to be used by a target.
Definition: MCInstrItineraries.h:109
llvm::R600Subtarget::hasVertexCache
bool hasVertexCache() const
Definition: R600Subtarget.h:130
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
getReg
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:580
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:22
write
static void write(bool isBE, void *P, T V)
Definition: RuntimeDyldELF.cpp:37
SmallSet.h
llvm::MachineOperand::isGlobal
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Definition: MachineOperand.h:336
llvm::R600InstrInfo::ALU_VEC_021_SCL_122
@ ALU_VEC_021_SCL_122
Definition: R600InstrInfo.h:62