LLVM: lib/Target/AMDGPU/R600InstrInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20

21using namespace llvm;

22

23#define GET_INSTRINFO_CTOR_DTOR

24#include "R600GenDFAPacketizer.inc"

25

26#define GET_INSTRINFO_CTOR_DTOR

27#define GET_INSTRMAP_INFO

28#define GET_INSTRINFO_NAMED_OPS

29#include "R600GenInstrInfo.inc"

30

33

36}

37

42 bool RenamableDest, bool RenamableSrc) 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++) {

60 RI.getSubReg(DestReg, SubRegIndex),

61 RI.getSubReg(SrcReg, SubRegIndex))

64 }

65 } else {

67 DestReg, SrcReg);

70 }

71}

72

73

78 return false;

79 return true;

80}

81

83 switch(Opcode) {

84 default:

85 return false;

86 case R600::MOV:

87 case R600::MOV_IMM_F32:

88 case R600::MOV_IMM_I32:

89 return true;

90 }

91}

92

94 return false;

95}

96

98 switch(Opcode) {

99 default: return false;

100 case R600::CUBE_r600_pseudo:

101 case R600::CUBE_r600_real:

102 case R600::CUBE_eg_pseudo:

103 case R600::CUBE_eg_real:

104 return true;

105 }

106}

107

109 unsigned TargetFlags = get(Opcode).TSFlags;

110

112}

113

115 unsigned TargetFlags = get(Opcode).TSFlags;

116

120}

121

123 unsigned TargetFlags = get(Opcode).TSFlags;

124

128}

129

132}

133

136 return true;

138 return true;

139 switch (MI.getOpcode()) {

140 case R600::PRED_X:

141 case R600::INTERP_PAIR_XY:

142 case R600::INTERP_PAIR_ZW:

143 case R600::INTERP_VEC_LOAD:

144 case R600::COPY:

145 case R600::DOT_4:

146 return true;

147 default:

148 return false;

149 }

150}

151

154 return false;

155 return (get(Opcode).getSchedClass() == R600::Sched::TransALU);

156}

157

160}

161

163 return (get(Opcode).getSchedClass() == R600::Sched::VecALU);

164}

165

168}

169

172}

173

176}

177

182}

183

186}

187

193}

194

196 switch (Opcode) {

197 case R600::KILLGT:

198 case R600::GROUP_BARRIER:

199 return true;

200 default:

201 return false;

202 }

203}

204

206 return MI.findRegisterUseOperandIdx(R600::AR_X, &RI, false) != -1;

207}

208

210 return MI.findRegisterDefOperandIdx(R600::AR_X, &RI, false, false) != -1;

211}

212

215 return false;

216 }

218 if (MO.getReg().isPhysical() &&

219 R600::R600_LDS_SRC_REGRegClass.contains(MO.getReg()))

220 return true;

221 return false;

222}

223

225 static const unsigned SrcSelTable[][2] = {

226 {R600::OpName::src0, R600::OpName::src0_sel},

227 {R600::OpName::src1, R600::OpName::src1_sel},

228 {R600::OpName::src2, R600::OpName::src2_sel},

229 {R600::OpName::src0_X, R600::OpName::src0_sel_X},

230 {R600::OpName::src0_Y, R600::OpName::src0_sel_Y},

231 {R600::OpName::src0_Z, R600::OpName::src0_sel_Z},

232 {R600::OpName::src0_W, R600::OpName::src0_sel_W},

233 {R600::OpName::src1_X, R600::OpName::src1_sel_X},

234 {R600::OpName::src1_Y, R600::OpName::src1_sel_Y},

235 {R600::OpName::src1_Z, R600::OpName::src1_sel_Z},

236 {R600::OpName::src1_W, R600::OpName::src1_sel_W}

237 };

238

239 for (const auto &Row : SrcSelTable) {

240 if (getOperandIdx(Opcode, Row[0]) == (int)SrcIdx) {

242 }

243 }

244 return -1;

245}

246

250

251 if (MI.getOpcode() == R600::DOT_4) {

252 static const unsigned OpTable[8][2] = {

253 {R600::OpName::src0_X, R600::OpName::src0_sel_X},

254 {R600::OpName::src0_Y, R600::OpName::src0_sel_Y},

255 {R600::OpName::src0_Z, R600::OpName::src0_sel_Z},

256 {R600::OpName::src0_W, R600::OpName::src0_sel_W},

257 {R600::OpName::src1_X, R600::OpName::src1_sel_X},

258 {R600::OpName::src1_Y, R600::OpName::src1_sel_Y},

259 {R600::OpName::src1_Z, R600::OpName::src1_sel_Z},

260 {R600::OpName::src1_W, R600::OpName::src1_sel_W},

261 };

262

263 for (const auto &Op : OpTable) {

266 if (Reg == R600::ALU_CONST) {

269 Result.push_back(std::pair(&MO, Sel.getImm()));

270 continue;

271 }

272 }

273 return Result;

274 }

275

276 static const unsigned OpTable[3][2] = {

277 {R600::OpName::src0, R600::OpName::src0_sel},

278 {R600::OpName::src1, R600::OpName::src1_sel},

279 {R600::OpName::src2, R600::OpName::src2_sel},

280 };

281

282 for (const auto &Op : OpTable) {

284 if (SrcIdx < 0)

285 break;

288 if (Reg == R600::ALU_CONST) {

290 Result.push_back(std::pair(&MO, Sel.getImm()));

291 continue;

292 }

293 if (Reg == R600::ALU_LITERAL_X) {

295 MI.getOperand(getOperandIdx(MI.getOpcode(), R600::OpName::literal));

296 if (Operand.isImm()) {

297 Result.push_back(std::pair(&MO, Operand.getImm()));

298 continue;

299 }

301 }

302 Result.push_back(std::pair(&MO, 0));

303 }

304 return Result;

305}

306

307std::vector<std::pair<int, unsigned>>

310 unsigned &ConstCount) const {

311 ConstCount = 0;

312 const std::pair<int, unsigned> DummyPair(-1, 0);

313 std::vector<std::pair<int, unsigned>> Result;

314 unsigned i = 0;

315 for (const auto &Src : getSrcs(MI)) {

316 ++i;

317 Register Reg = Src.first->getReg();

318 int Index = RI.getEncodingValue(Reg) & 0xff;

319 if (Reg == R600::OQAP) {

320 Result.emplace_back(Index, 0U);

321 }

323

324 Result.emplace_back(255, 0U);

325 continue;

326 }

327 if (Index > 127) {

328 ConstCount++;

329 Result.push_back(DummyPair);

330 continue;

331 }

333 Result.emplace_back(Index, Chan);

334 }

335 for (; i < 3; ++i)

336 Result.push_back(DummyPair);

338}

339

340static std::vector<std::pair<int, unsigned>>

341Swizzle(std::vector<std::pair<int, unsigned>> Src,

343 if (Src[0] == Src[1])

344 Src[1].first = -1;

345 switch (Swz) {

347 break;

350 break;

353 break;

357 break;

361 break;

364 break;

365 }

366 return Src;

367}

368

370 assert(Op < 3 && "Out of range swizzle index");

371 switch (Swz) {

373 unsigned Cycles[3] = { 2, 1, 0};

374 return Cycles[Op];

375 }

377 unsigned Cycles[3] = { 1, 2, 2};

378 return Cycles[Op];

379 }

381 unsigned Cycles[3] = { 2, 1, 2};

382 return Cycles[Op];

383 }

385 unsigned Cycles[3] = { 2, 2, 1};

386 return Cycles[Op];

387 }

388 default:

390 }

391}

392

393

394

395

397 const std::vector<std::vector<std::pair<int, unsigned>>> &IGSrcs,

398 const std::vectorR600InstrInfo::BankSwizzle &Swz,

399 const std::vector<std::pair<int, unsigned>> &TransSrcs,

403 for (unsigned i = 0, e = IGSrcs.size(); i < e; i++) {

404 const std::vector<std::pair<int, unsigned>> &Srcs =

405 Swizzle(IGSrcs[i], Swz[i]);

406 for (unsigned j = 0; j < 3; j++) {

407 const std::pair<int, unsigned> &Src = Srcs[j];

408 if (Src.first < 0 || Src.first == 255)

409 continue;

410 if (Src.first == GET_REG_INDEX(RI.getEncodingValue(R600::OQAP))) {

413

414

415 return false;

416 }

417

418 continue;

419 }

420 if (Vector[Src.second][j] < 0)

421 Vector[Src.second][j] = Src.first;

422 if (Vector[Src.second][j] != Src.first)

423 return i;

424 }

425 }

426

427 for (unsigned i = 0, e = TransSrcs.size(); i < e; ++i) {

428 const std::pair<int, unsigned> &Src = TransSrcs[i];

430 if (Src.first < 0)

431 continue;

432 if (Src.first == 255)

433 continue;

436 if (Vector[Src.second][Cycle] != Src.first)

437 return IGSrcs.size() - 1;

438 }

439 return IGSrcs.size();

440}

441

442

443

444

445static bool

447 std::vectorR600InstrInfo::BankSwizzle &SwzCandidate,

448 unsigned Idx) {

449 assert(Idx < SwzCandidate.size());

450 int ResetIdx = Idx;

452 ResetIdx --;

453 for (unsigned i = ResetIdx + 1, e = SwzCandidate.size(); i < e; i++) {

455 }

456 if (ResetIdx == -1)

457 return false;

458 int NextSwizzle = SwzCandidate[ResetIdx] + 1;

460 return true;

461}

462

463

464

466 const std::vector<std::vector<std::pair<int, unsigned>>> &IGSrcs,

467 std::vectorR600InstrInfo::BankSwizzle &SwzCandidate,

468 const std::vector<std::pair<int, unsigned>> &TransSrcs,

470 unsigned ValidUpTo = 0;

471 do {

472 ValidUpTo = isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz);

473 if (ValidUpTo == IGSrcs.size())

474 return true;

476 return false;

477}

478

479

480

481static bool

483 const std::vector<std::pair<int, unsigned>> &TransOps,

484 unsigned ConstCount) {

485

486 if (ConstCount > 2)

487 return false;

488 for (unsigned i = 0, e = TransOps.size(); i < e; ++i) {

489 const std::pair<int, unsigned> &Src = TransOps[i];

491 if (Src.first < 0)

492 continue;

493 if (ConstCount > 0 && Cycle == 0)

494 return false;

495 if (ConstCount > 1 && Cycle == 1)

496 return false;

497 }

498 return true;

499}

500

501bool

504 std::vector &ValidSwizzle,

505 bool isLastAluTrans)

506 const {

507

508

509 std::vector<std::vector<std::pair<int, unsigned>>> IGSrcs;

510 ValidSwizzle.clear();

511 unsigned ConstCount;

514 IGSrcs.push_back(ExtractSrcs(*MI, PV, ConstCount));

515 unsigned Op = getOperandIdx(MI->getOpcode(), R600::OpName::bank_swizzle);

516 ValidSwizzle.push_back(

518 }

519 std::vector<std::pair<int, unsigned>> TransOps;

520 if (!isLastAluTrans)

522

523 TransOps = std::move(IGSrcs.back());

524 IGSrcs.pop_back();

525 ValidSwizzle.pop_back();

526

532 };

535 continue;

537 TransBS);

538 if (Result) {

539 ValidSwizzle.push_back(TransBS);

540 return true;

541 }

542 }

543

544 return false;

545}

546

547bool

549 const {

550 assert (Consts.size() <= 12 && "Too many operands in instructions group");

551 unsigned Pair1 = 0, Pair2 = 0;

552 for (unsigned Const : Consts) {

553 unsigned ReadConstHalf = Const & 2;

554 unsigned ReadConstIndex = Const & (~3);

555 unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;

556 if (!Pair1) {

557 Pair1 = ReadHalfConst;

558 continue;

559 }

560 if (Pair1 == ReadHalfConst)

561 continue;

562 if (!Pair2) {

563 Pair2 = ReadHalfConst;

564 continue;

565 }

566 if (Pair2 != ReadHalfConst)

567 return false;

568 }

569 return true;

570}

571

572bool

574 const {

575 std::vector Consts;

579 continue;

580

581 for (const auto &Src : getSrcs(*MI)) {

582 if (Src.first->getReg() == R600::ALU_LITERAL_X)

583 Literals.insert(Src.second);

584 if (Literals.size() > 4)

585 return false;

586 if (Src.first->getReg() == R600::ALU_CONST)

587 Consts.push_back(Src.second);

588 if (R600::R600_KC0RegClass.contains(Src.first->getReg()) ||

589 R600::R600_KC1RegClass.contains(Src.first->getReg())) {

590 unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff;

591 unsigned Chan = RI.getHWRegChan(Src.first->getReg());

592 Consts.push_back((Index << 2) | Chan);

593 }

594 }

595 }

597}

598

602 return static_cast<const R600Subtarget &>(STI).createDFAPacketizer(II);

603}

604

605static bool

607 switch (Opcode) {

608 case R600::PRED_X:

609 return true;

610 default:

611 return false;

612 }

613}

614

619 --I;

622 return &MI;

623 }

624

625 return nullptr;

626}

627

628static

630 return Opcode == R600::JUMP || Opcode == R600::JUMP_COND;

631}

632

634 return Opcode == R600::BRANCH || Opcode == R600::BRANCH_COND_i32 ||

635 Opcode == R600::BRANCH_COND_f32;

636}

637

642 bool AllowModify) const {

643

644

645

648 return false;

649

650

651

653 return true;

654 if (isJump(I->getOpcode())) {

655 return false;

656 }

657

658

659 while (I != MBB.begin() && std::prev(I)->getOpcode() == R600::JUMP) {

661 if (AllowModify)

662 I->removeFromParent();

663 I = PriorI;

664 }

666

667

668 unsigned LastOpc = LastInst.getOpcode();

670 if (LastOpc == R600::JUMP) {

672 return false;

673 }

674 if (LastOpc == R600::JUMP_COND) {

675 auto predSet = I;

677 predSet = --I;

678 }

680 Cond.push_back(predSet->getOperand(1));

681 Cond.push_back(predSet->getOperand(2));

683 return false;

684 }

685 return true;

686 }

687

688

690 unsigned SecondLastOpc = SecondLastInst.getOpcode();

691

692

693 if (SecondLastOpc == R600::JUMP_COND && LastOpc == R600::JUMP) {

694 auto predSet = --I;

696 predSet = --I;

697 }

700 Cond.push_back(predSet->getOperand(1));

701 Cond.push_back(predSet->getOperand(2));

703 return false;

704 }

705

706

707 return true;

708}

709

710static

713 It != E; ++It) {

714 if (It->getOpcode() == R600::CF_ALU ||

715 It->getOpcode() == R600::CF_ALU_PUSH_BEFORE)

717 }

719}

720

726 int *BytesAdded) const {

727 assert(TBB && "insertBranch must not be told to insert a fallthrough");

728 assert(!BytesAdded && "code size not handled");

729

730 if (!FBB) {

731 if (Cond.empty()) {

733 return 1;

734 }

736 assert(PredSet && "No previous predicate !");

739

744 if (CfAlu == MBB.end())

745 return 1;

746 assert (CfAlu->getOpcode() == R600::CF_ALU);

747 CfAlu->setDesc(get(R600::CF_ALU_PUSH_BEFORE));

748 return 1;

749 }

751 assert(PredSet && "No previous predicate !");

759 if (CfAlu == MBB.end())

760 return 2;

761 assert(CfAlu->getOpcode() == R600::CF_ALU);

762 CfAlu->setDesc(get(R600::CF_ALU_PUSH_BEFORE));

763 return 2;

764}

765

767 int *BytesRemoved) const {

768 assert(!BytesRemoved && "code size not handled");

769

770

771

772

774

776 return 0;

777 }

778 --I;

779 switch (I->getOpcode()) {

780 default:

781 return 0;

782 case R600::JUMP_COND: {

785 I->eraseFromParent();

787 if (CfAlu == MBB.end())

788 break;

789 assert (CfAlu->getOpcode() == R600::CF_ALU_PUSH_BEFORE);

790 CfAlu->setDesc(get(R600::CF_ALU));

791 break;

792 }

793 case R600::JUMP:

794 I->eraseFromParent();

795 break;

796 }

798

800 return 1;

801 }

802 --I;

803 switch (I->getOpcode()) {

804

805 default:

806 return 1;

807 case R600::JUMP_COND: {

810 I->eraseFromParent();

812 if (CfAlu == MBB.end())

813 break;

814 assert (CfAlu->getOpcode() == R600::CF_ALU_PUSH_BEFORE);

815 CfAlu->setDesc(get(R600::CF_ALU));

816 break;

817 }

818 case R600::JUMP:

819 I->eraseFromParent();

820 break;

821 }

822 return 2;

823}

824

826 int idx = MI.findFirstPredOperandIdx();

827 if (idx < 0)

828 return false;

829

830 Register Reg = MI.getOperand(idx).getReg();

831 switch (Reg) {

832 default: return false;

833 case R600::PRED_SEL_ONE:

834 case R600::PRED_SEL_ZERO:

835 case R600::PREDICATE_BIT:

836 return true;

837 }

838}

839

841

842

843

844

845

846 if (MI.getOpcode() == R600::KILLGT)

847 return false;

848 if (MI.getOpcode() == R600::CF_ALU) {

849

850

852 return false;

853

854 return MI.getOperand(3).getImm() == 0 && MI.getOperand(4).getImm() == 0;

855 }

857 return false;

859}

860

861bool

863 unsigned NumCycles,

864 unsigned ExtraPredCycles,

866 return true;

867}

868

869bool

871 unsigned NumTCycles,

872 unsigned ExtraTCycles,

874 unsigned NumFCycles,

875 unsigned ExtraFCycles,

877 return true;

878}

879

880bool

882 unsigned NumCycles,

884 const {

885 return true;

886}

887

888bool

891 return false;

892}

893

894bool

897 switch (MO.getImm()) {

898 case R600::PRED_SETE_INT:

899 MO.setImm(R600::PRED_SETNE_INT);

900 break;

901 case R600::PRED_SETNE_INT:

902 MO.setImm(R600::PRED_SETE_INT);

903 break;

904 case R600::PRED_SETE:

905 MO.setImm(R600::PRED_SETNE);

906 break;

907 case R600::PRED_SETNE:

908 MO.setImm(R600::PRED_SETE);

909 break;

910 default:

911 return true;

912 }

913

915 switch (MO2.getReg()) {

916 case R600::PRED_SEL_ZERO:

917 MO2.setReg(R600::PRED_SEL_ONE);

918 break;

919 case R600::PRED_SEL_ONE:

920 MO2.setReg(R600::PRED_SEL_ZERO);

921 break;

922 default:

923 return true;

924 }

925 return false;

926}

927

929 std::vector &Pred,

930 bool SkipDead) const {

932}

933

936 int PIdx = MI.findFirstPredOperandIdx();

937

938 if (MI.getOpcode() == R600::CF_ALU) {

939 MI.getOperand(8).setImm(0);

940 return true;

941 }

942

943 if (MI.getOpcode() == R600::DOT_4) {

945 .setReg(Pred[2].getReg());

947 .setReg(Pred[2].getReg());

949 .setReg(Pred[2].getReg());

951 .setReg(Pred[2].getReg());

954 return true;

955 }

956

957 if (PIdx != -1) {

962 return true;

963 }

964

965 return false;

966}

967

969 return 2;

970}

971

974 unsigned *PredCost) const {

975 if (PredCost)

976 *PredCost = 2;

977 return 2;

978}

979

981 unsigned Channel) const {

982 assert(Channel == 0);

983 return RegIndex;

984}

985

987 switch (MI.getOpcode()) {

988 default: {

990 int OffsetOpIdx =

991 R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::addr);

992

993

994 int RegOpIdx = OffsetOpIdx + 1;

995 int ChanOpIdx =

996 R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::chan);

998 int DstOpIdx =

999 R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::dst);

1000 unsigned RegIndex = MI.getOperand(RegOpIdx).getImm();

1001 unsigned Channel = MI.getOperand(ChanOpIdx).getImm();

1003 Register OffsetReg = MI.getOperand(OffsetOpIdx).getReg();

1004 if (OffsetReg == R600::INDIRECT_BASE_ADDR) {

1007 } else {

1008 buildIndirectRead(MBB, MI, MI.getOperand(DstOpIdx).getReg(), Address,

1009 OffsetReg);

1010 }

1012 int ValOpIdx =

1013 R600::getNamedOperandIdx(MI.getOpcode(), R600::OpName::val);

1014 unsigned RegIndex = MI.getOperand(RegOpIdx).getImm();

1015 unsigned Channel = MI.getOperand(ChanOpIdx).getImm();

1017 Register OffsetReg = MI.getOperand(OffsetOpIdx).getReg();

1018 if (OffsetReg == R600::INDIRECT_BASE_ADDR) {

1020 MI.getOperand(ValOpIdx).getReg());

1021 } else {

1022 buildIndirectWrite(MBB, MI, MI.getOperand(ValOpIdx).getReg(),

1024 OffsetReg);

1025 }

1026 } else {

1027 return false;

1028 }

1029

1031 return true;

1032 }

1033 case R600::R600_EXTRACT_ELT_V2:

1034 case R600::R600_EXTRACT_ELT_V4:

1035 buildIndirectRead(MI.getParent(), MI, MI.getOperand(0).getReg(),

1037 MI.getOperand(2).getReg(),

1039 break;

1040 case R600::R600_INSERT_ELT_V2:

1041 case R600::R600_INSERT_ELT_V4:

1042 buildIndirectWrite(MI.getParent(), MI, MI.getOperand(2).getReg(),

1044 MI.getOperand(3).getReg(),

1045 RI.getHWRegChan(MI.getOperand(1).getReg()));

1046 break;

1047 }

1048 MI.eraseFromParent();

1049 return true;

1050}

1051

1057

1058 unsigned StackWidth = TFL->getStackWidth(MF);

1060

1061 if (End == -1)

1062 return;

1063

1065 for (unsigned Chan = 0; Chan < StackWidth; ++Chan) {

1066 unsigned Reg = R600::R600_TReg32RegClass.getRegister((4 * Index) + Chan);

1067 TRI.reserveRegisterTuples(Reserved, Reg);

1068 }

1069 }

1070}

1071

1073 return &R600::R600_TReg32_XRegClass;

1074}

1075

1078 unsigned ValueReg, unsigned Address,

1079 unsigned OffsetReg) const {

1080 return buildIndirectWrite(MBB, I, ValueReg, Address, OffsetReg, 0);

1081}

1082

1085 unsigned ValueReg, unsigned Address,

1086 unsigned OffsetReg,

1087 unsigned AddrChan) const {

1088 unsigned AddrReg;

1089 switch (AddrChan) {

1091 case 0: AddrReg = R600::R600_AddrRegClass.getRegister(Address); break;

1092 case 1: AddrReg = R600::R600_Addr_YRegClass.getRegister(Address); break;

1093 case 2: AddrReg = R600::R600_Addr_ZRegClass.getRegister(Address); break;

1094 case 3: AddrReg = R600::R600_Addr_WRegClass.getRegister(Address); break;

1095 }

1097 R600::AR_X, OffsetReg);

1099

1101 AddrReg, ValueReg)

1105 return Mov;

1106}

1107

1110 unsigned ValueReg, unsigned Address,

1111 unsigned OffsetReg) const {

1112 return buildIndirectRead(MBB, I, ValueReg, Address, OffsetReg, 0);

1113}

1114

1117 unsigned ValueReg, unsigned Address,

1118 unsigned OffsetReg,

1119 unsigned AddrChan) const {

1120 unsigned AddrReg;

1121 switch (AddrChan) {

1123 case 0: AddrReg = R600::R600_AddrRegClass.getRegister(Address); break;

1124 case 1: AddrReg = R600::R600_Addr_YRegClass.getRegister(Address); break;

1125 case 2: AddrReg = R600::R600_Addr_ZRegClass.getRegister(Address); break;

1126 case 3: AddrReg = R600::R600_Addr_WRegClass.getRegister(Address); break;

1127 }

1129 R600::AR_X,

1130 OffsetReg);

1133 ValueReg,

1134 AddrReg)

1138

1139 return Mov;

1140}

1141

1146

1148 return -1;

1149 }

1150

1151 if (MRI.livein_empty()) {

1152 return 0;

1153 }

1154

1156 for (std::pair<MCRegister, Register> LI : MRI.liveins()) {

1158 if (Reg.isVirtual() || !IndirectRC->contains(Reg))

1159 continue;

1160

1161 unsigned RegIndex;

1162 unsigned RegEnd;

1163 for (RegIndex = 0, RegEnd = IndirectRC->getNumRegs(); RegIndex != RegEnd;

1164 ++RegIndex) {

1165 if (IndirectRC->getRegister(RegIndex) == (unsigned)Reg)

1166 break;

1167 }

1169 }

1170

1172}

1173

1177

1178

1180 return -1;

1181 }

1182

1184 return -1;

1185 }

1186

1189

1191 Offset = TFL->getFrameIndexReference(MF, -1, IgnoredFrameReg).getFixed();

1192

1194}

1195

1197 return 115;

1198}

1199

1202 unsigned Opcode,

1203 unsigned DstReg,

1204 unsigned Src0Reg,

1205 unsigned Src1Reg) const {

1207 DstReg);

1208

1209 if (Src1Reg) {

1210 MIB.addImm(0)

1211 .addImm(0);

1212 }

1213 MIB.addImm(1)

1215 .addImm(0)

1216 .addImm(0)

1217 .addReg(Src0Reg)

1218 .addImm(0)

1219 .addImm(0)

1220 .addImm(0)

1221 .addImm(-1);

1222

1223 if (Src1Reg) {

1224 MIB.addReg(Src1Reg)

1225 .addImm(0)

1226 .addImm(0)

1227 .addImm(0)

1228 .addImm(-1);

1229 }

1230

1231

1232

1233 MIB.addImm(1)

1234 .addReg(R600::PRED_SEL_OFF)

1235 .addImm(0)

1236 .addImm(0);

1237

1238 return MIB;

1239}

1240

1241#define OPERAND_CASE(Label) \

1242 case Label: { \

1243 static const unsigned Ops[] = \

1244 { \

1245 Label##_X, \

1246 Label##_Y, \

1247 Label##_Z, \

1248 Label##_W \

1249 }; \

1250 return Ops[Slot]; \

1251 }

1252

1254 switch (Op) {

1255 OPERAND_CASE(R600::OpName::update_exec_mask)

1272 default:

1274 }

1275}

1276

1277#undef OPERAND_CASE

1278

1281 const {

1282 assert (MI->getOpcode() == R600::DOT_4 && "Not Implemented");

1283 unsigned Opcode;

1285 Opcode = R600::DOT4_r600;

1286 else

1287 Opcode = R600::DOT4_eg;

1295 static const unsigned Operands[14] = {

1296 R600::OpName::update_exec_mask,

1297 R600::OpName::update_pred,

1298 R600::OpName::write,

1299 R600::OpName::omod,

1300 R600::OpName::dst_rel,

1301 R600::OpName::clamp,

1302 R600::OpName::src0_neg,

1303 R600::OpName::src0_rel,

1304 R600::OpName::src0_abs,

1305 R600::OpName::src0_sel,

1306 R600::OpName::src1_neg,

1307 R600::OpName::src1_rel,

1308 R600::OpName::src1_abs,

1309 R600::OpName::src1_sel,

1310 };

1311

1313 getSlotedOps(R600::OpName::pred_sel, Slot)));

1316

1317 for (unsigned Operand : Operands) {

1322 }

1324 return MIB;

1325}

1326

1329 unsigned DstReg,

1332 R600::ALU_LITERAL_X);

1333 setImmOperand(*MovImm, R600::OpName::literal, Imm);

1334 return MovImm;

1335}

1336

1339 unsigned DstReg, unsigned SrcReg) const {

1341}

1342

1345}

1346

1348 return R600::getNamedOperandIdx(Opcode, Op);

1349}

1350

1352 int64_t Imm) const {

1354 assert(Idx != -1 && "Operand not supported for this instruction.");

1356 MI.getOperand(Idx).setImm(Imm);

1357}

1358

1359

1360

1361

1362

1364 unsigned Flag) const {

1365 unsigned TargetFlags = get(MI.getOpcode()).TSFlags;

1366 int FlagIndex = 0;

1367 if (Flag != 0) {

1368

1369

1370

1373 switch (Flag) {

1376 break;

1379 break;

1383 break;

1385 switch (SrcIdx) {

1386 case 0:

1388 break;

1389 case 1:

1391 break;

1392 case 2:

1394 break;

1395 }

1396 break;

1397

1399 assert(!IsOP3 && "Cannot set absolute value modifier for OP3 "

1400 "instructions.");

1401 (void)IsOP3;

1402 switch (SrcIdx) {

1403 case 0:

1405 break;

1406 case 1:

1408 break;

1409 }

1410 break;

1411

1412 default:

1413 FlagIndex = -1;

1414 break;

1415 }

1416 assert(FlagIndex != -1 && "Flag not supported for this instruction");

1417 } else {

1419 assert(FlagIndex != 0 &&

1420 "Instruction flags not supported for this instruction");

1421 }

1422

1425 return FlagOp;

1426}

1427

1429 unsigned Flag) const {

1430 unsigned TargetFlags = get(MI.getOpcode()).TSFlags;

1431 if (Flag == 0) {

1432 return;

1433 }

1440 } else {

1442 }

1443 } else {

1446 }

1447}

1448

1450 unsigned Flag) const {

1451 unsigned TargetFlags = get(MI.getOpcode()).TSFlags;

1455 } else {

1457 unsigned InstFlags = FlagOp.getImm();

1458 InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand));

1459 FlagOp.setImm(InstFlags);

1460 }

1461}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

mir Rename Register Operands

unsigned const TargetRegisterInfo * TRI

static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

uint64_t IntrinsicInst * II

#define GET_REG_INDEX(reg)

#define HAS_NATIVE_OPERANDS(Flags)

#define GET_FLAG_OPERAND_IDX(Flags)

Helper for getting the operand index for the instruction flags operand.

static MachineInstr * findFirstPredicateSetterFrom(MachineBasicBlock &MBB, MachineBasicBlock::iterator I)

static bool isBranch(unsigned Opcode)

static MachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB)

#define OPERAND_CASE(Label)

static std::vector< std::pair< int, unsigned > > Swizzle(std::vector< std::pair< int, unsigned > > Src, R600InstrInfo::BankSwizzle Swz)

static unsigned getTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op)

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 ...

static bool isPredicateSetter(unsigned Opcode)

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...

static unsigned getSlotedOps(unsigned Op, unsigned Slot)

static bool isJump(unsigned Opcode)

Interface definition for R600InstrInfo.

Provides R600 specific target descriptions.

AMDGPU R600 specific subclass of TargetSubtarget.

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallSet class.

static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)

Returns the opcode of Values or ~0 if they do not all agree.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

This class represents an Operation in the Expression.

bool contains(const_arg_type_t< KeyT > Val) const

Return true if the specified key is in the map, false otherwise.

CallingConv::ID getCallingConv() const

getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...

A possibly irreducible generalization of a Loop.

Itinerary data supplied by a subtarget to be used by a target.

Wrapper class representing physical registers. Should be passed by value.

DebugLoc findDebugLoc(instr_iterator MBBI)

Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.

iterator getLastNonDebugInstr(bool SkipPseudoOp=true)

Returns an iterator to the last non-debug instruction in the basic block, or end().

instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

reverse_iterator rbegin()

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

bool hasVarSizedObjects() const

This method may be called any time after instruction selection is complete to determine if the stack ...

unsigned getNumObjects() const

Return the number of objects.

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

reverse_iterator getReverse() const

Get a reverse iterator to the same node.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

void setImm(int64_t immVal)

MachineBasicBlock * getMBB() const

void setReg(Register Reg)

Change the register this operand corresponds to.

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

void setIsKill(bool Val=true)

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

Register getReg() const

getReg - Returns the register number.

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)

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

bool usesVertexCache(unsigned Opcode) const

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...

bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override

bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override

bool usesAddressRegister(MachineInstr &MI) const

unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const

Calculate the "Indirect Address" for the given RegIndex and Channel.

bool hasInstrModifiers(unsigned Opcode) const

R600InstrInfo(const R600Subtarget &)

bool isMov(unsigned Opcode) const

bool isRegisterLoad(const MachineInstr &MI) const

int getIndirectIndexBegin(const MachineFunction &MF) const

bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override

bool usesTextureCache(unsigned Opcode) const

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...

unsigned int getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override

const TargetRegisterClass * getIndirectAddrRegClass() const

MachineInstr * buildMovImm(MachineBasicBlock &BB, MachineBasicBlock::iterator I, unsigned DstReg, uint64_t Imm) const

bool definesAddressRegister(MachineInstr &MI) const

unsigned getMaxAlusPerClause() const

bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override

bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override

bool canBeConsideredALU(const MachineInstr &MI) const

bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const override

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+.

void addFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const

Add one of the MO_FLAG* flags to the specified Operand.

bool isVector(const MachineInstr &MI) const

Vector instructions are instructions that must fill all instruction slots within an instruction group...

unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override

bool mustBeLastInClause(unsigned Opcode) const

unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override

int getIndirectIndexEnd(const MachineFunction &MF) const

bool isTransOnly(unsigned Opcode) const

DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const override

bool isReductionOp(unsigned opcode) const

bool isRegisterStore(const MachineInstr &MI) const

bool isCubeOp(unsigned opcode) const

bool isLDSInstr(unsigned Opcode) const

void reserveIndirectRegisters(BitVector &Reserved, const MachineFunction &MF, const R600RegisterInfo &TRI) const

Reserve the registers that may be accessed using indirect addressing.

bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override

bool isPredicable(const MachineInstr &MI) const override

bool isPredicated(const MachineInstr &MI) const override

bool expandPostRAPseudo(MachineInstr &MI) const override

bool isLDSRetInstr(unsigned Opcode) const

int getSelIdx(unsigned Opcode, unsigned SrcIdx) const

MachineOperand & getFlagOp(MachineInstr &MI, unsigned SrcIdx=0, unsigned Flag=0) const

unsigned int getPredicationCost(const MachineInstr &) const override

MachineInstr * buildSlotOfVectorInstruction(MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg) const

bool readsLDSSrcReg(const MachineInstr &MI) const

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.

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 ...

bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override

bool isALUInstr(unsigned Opcode) const

bool isVectorOnly(unsigned Opcode) const

bool isExport(unsigned Opcode) const

int getOperandIdx(const MachineInstr &MI, unsigned Op) const

Get the index of Op in the MachineInstr.

SmallVector< std::pair< MachineOperand *, int64_t >, 3 > getSrcs(MachineInstr &MI) const

void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override

void setImmOperand(MachineInstr &MI, unsigned Op, int64_t Imm) const

Helper function for setting instruction flag values.

MachineInstr * buildMovInstr(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned DstReg, unsigned SrcReg) const

void clearFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const

Clear the specified flag on the instruction.

bool hasVertexCache() const

bool hasCaymanISA() const

Generation getGeneration() const

Wrapper class representing virtual and physical registers.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

virtual bool isPredicable(const MachineInstr &MI) const

Return true if the specified instruction can be predicated.

unsigned getNumRegs() const

Return the number of registers in this class.

bool contains(Register Reg) const

Return true if the specified register is included in this register class.

MCRegister getRegister(unsigned i) const

Return the specified register in the class.

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual const InstrItineraryData * getInstrItineraryData() const

getInstrItineraryData - Returns instruction itinerary data for the target or specific subtarget.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

bool isCompute(CallingConv::ID cc)

@ Implicit

Not emitted register (e.g. carry, or temporary result).

@ Define

Register definition.

@ Kill

The last use of a register.

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

DWARFExpression::Operation Op

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

unsigned getHWRegIndex(unsigned Reg) const

unsigned getHWRegChan(unsigned reg) const

get the HW encoding for a register's channel.

static unsigned getSubRegFromChannel(unsigned Channel)

bool isPhysRegLiveAcrossClauses(Register Reg) const