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