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