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