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

37

41 Register SrcReg, bool KillSrc,

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

77 if (!MO.getReg().isVirtual() && RI.isPhysRegLiveAcrossClauses(MO.getReg()))

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

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

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

153 if (ST.hasCaymanISA())

154 return false;

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

156}

157

161

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

164}

165

169

173

175 return ST.hasVertexCache() && IS_VTX(get(Opcode));

176}

177

183

187

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 R600::OpName 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 for (const auto &Row : SrcSelTable) {

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

241 }

242 }

243 return -1;

244}

245

249

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

251 static const R600::OpName OpTable[8][2] = {

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

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

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

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

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

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

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

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

260 };

261

262 for (const auto &Op : OpTable) {

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

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

269 continue;

270 }

271 }

272 return Result;

273 }

274

275 static const R600::OpName OpTable[3][2] = {

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

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

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

279 };

280

281 for (const auto &Op : OpTable) {

283 if (SrcIdx < 0)

284 break;

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

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

290 continue;

291 }

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

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

295 if (Operand.isImm()) {

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

297 continue;

298 }

300 }

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

302 }

303 return Result;

304}

305

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

309 unsigned &ConstCount) const {

310 ConstCount = 0;

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

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

313 unsigned i = 0;

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

315 ++i;

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

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

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

319 Result.emplace_back(Index, 0U);

320 }

322

323 Result.emplace_back(255, 0U);

324 continue;

325 }

326 if (Index > 127) {

327 ConstCount++;

328 Result.push_back(DummyPair);

329 continue;

330 }

332 Result.emplace_back(Index, Chan);

333 }

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

335 Result.push_back(DummyPair);

337}

338

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

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

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

343 Src[1].first = -1;

344 switch (Swz) {

346 break;

349 break;

352 break;

356 break;

360 break;

363 break;

364 }

365 return Src;

366}

367

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

370 switch (Swz) {

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

373 return Cycles[Op];

374 }

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

377 return Cycles[Op];

378 }

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

381 return Cycles[Op];

382 }

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

385 return Cycles[Op];

386 }

387 default:

389 }

390}

391

392

393

394

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

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

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

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

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

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

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

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

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

408 continue;

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

412

413

414 return false;

415 }

416

417 continue;

418 }

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

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

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

422 return i;

423 }

424 }

425

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

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

429 if (Src.first < 0)

430 continue;

431 if (Src.first == 255)

432 continue;

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

436 return IGSrcs.size() - 1;

437 }

438 return IGSrcs.size();

439}

440

441

442

443

444static bool

446 std::vectorR600InstrInfo::BankSwizzle &SwzCandidate,

447 unsigned Idx) {

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

449 int ResetIdx = Idx;

451 ResetIdx --;

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

454 }

455 if (ResetIdx == -1)

456 return false;

457 int NextSwizzle = SwzCandidate[ResetIdx] + 1;

459 return true;

460}

461

462

463

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

466 std::vectorR600InstrInfo::BankSwizzle &SwzCandidate,

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

469 unsigned ValidUpTo = 0;

470 do {

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

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

473 return true;

475 return false;

476}

477

478

479

480static bool

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

483 unsigned ConstCount) {

484

485 if (ConstCount > 2)

486 return false;

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

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

490 if (Src.first < 0)

491 continue;

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

493 return false;

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

495 return false;

496 }

497 return true;

498}

499

500bool

503 std::vector &ValidSwizzle,

504 bool isLastAluTrans)

505 const {

506

507

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

509 ValidSwizzle.clear();

510 unsigned ConstCount;

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

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

515 ValidSwizzle.push_back(

517 }

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

519 if (!isLastAluTrans)

521

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

523 IGSrcs.pop_back();

524 ValidSwizzle.pop_back();

525

531 };

534 continue;

536 TransBS);

537 if (Result) {

538 ValidSwizzle.push_back(TransBS);

539 return true;

540 }

541 }

542

543 return false;

544}

545

546bool

548 const {

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

550 unsigned Pair1 = 0, Pair2 = 0;

551 for (unsigned Const : Consts) {

552 unsigned ReadConstHalf = Const & 2;

553 unsigned ReadConstIndex = Const & (~3);

554 unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf;

555 if (!Pair1) {

556 Pair1 = ReadHalfConst;

557 continue;

558 }

559 if (Pair1 == ReadHalfConst)

560 continue;

561 if (!Pair2) {

562 Pair2 = ReadHalfConst;

563 continue;

564 }

565 if (Pair2 != ReadHalfConst)

566 return false;

567 }

568 return true;

569}

570

571bool

573 const {

574 std::vector Consts;

578 continue;

579

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

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

582 Literals.insert(Src.second);

583 if (Literals.size() > 4)

584 return false;

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

586 Consts.push_back(Src.second);

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

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

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

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

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

592 }

593 }

594 }

596}

597

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

602}

603

604static bool

606 switch (Opcode) {

607 case R600::PRED_X:

608 return true;

609 default:

610 return false;

611 }

612}

613

617 while (I != MBB.begin()) {

618 --I;

621 return &MI;

622 }

623

624 return nullptr;

625}

626

627static

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

630}

631

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

634 Opcode == R600::BRANCH_COND_f32;

635}

636

641 bool AllowModify) const {

642

643

644

646 if (I == MBB.end())

647 return false;

648

649

650

652 return true;

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

654 return false;

655 }

656

657

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

660 if (AllowModify)

661 I->removeFromParent();

662 I = PriorI;

663 }

665

666

667 unsigned LastOpc = LastInst.getOpcode();

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

671 return false;

672 }

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

674 auto predSet = I;

676 predSet = --I;

677 }

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

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

682 return false;

683 }

684 return true;

685 }

686

687

689 unsigned SecondLastOpc = SecondLastInst.getOpcode();

690

691

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

693 auto predSet = --I;

695 predSet = --I;

696 }

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

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

702 return false;

703 }

704

705

706 return true;

707}

708

709static

712 It != E; ++It) {

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

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

715 return It.getReverse();

716 }

717 return MBB.end();

718}

719

725 int *BytesAdded) const {

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

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

728

729 if (!FBB) {

730 if (Cond.empty()) {

732 return 1;

733 }

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

738

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

744 return 1;

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

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

747 return 1;

748 }

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

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

759 return 2;

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

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

762 return 2;

763}

764

766 int *BytesRemoved) const {

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

768

769

770

771

773

774 if (I == MBB.begin()) {

775 return 0;

776 }

777 --I;

778 switch (I->getOpcode()) {

779 default:

780 return 0;

781 case R600::JUMP_COND: {

784 I->eraseFromParent();

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

787 break;

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

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

790 break;

791 }

792 case R600::JUMP:

793 I->eraseFromParent();

794 break;

795 }

796 I = MBB.end();

797

798 if (I == MBB.begin()) {

799 return 1;

800 }

801 --I;

802 switch (I->getOpcode()) {

803

804 default:

805 return 1;

806 case R600::JUMP_COND: {

809 I->eraseFromParent();

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

812 break;

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

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

815 break;

816 }

817 case R600::JUMP:

818 I->eraseFromParent();

819 break;

820 }

821 return 2;

822}

823

825 int idx = MI.findFirstPredOperandIdx();

826 if (idx < 0)

827 return false;

828

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

830 switch (Reg) {

831 default: return false;

832 case R600::PRED_SEL_ONE:

833 case R600::PRED_SEL_ZERO:

834 case R600::PREDICATE_BIT:

835 return true;

836 }

837}

838

840

841

842

843

844

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

846 return false;

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

848

849

851 return false;

852

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

854 }

856 return false;

858}

859

860bool

862 unsigned NumCycles,

863 unsigned ExtraPredCycles,

865 return true;

866}

867

868bool

870 unsigned NumTCycles,

871 unsigned ExtraTCycles,

873 unsigned NumFCycles,

874 unsigned ExtraFCycles,

876 return true;

877}

878

879bool

881 unsigned NumCycles,

883 const {

884 return true;

885}

886

887bool

892

893bool

896 switch (MO.getImm()) {

897 case R600::PRED_SETE_INT:

898 MO.setImm(R600::PRED_SETNE_INT);

899 break;

900 case R600::PRED_SETNE_INT:

901 MO.setImm(R600::PRED_SETE_INT);

902 break;

903 case R600::PRED_SETE:

904 MO.setImm(R600::PRED_SETNE);

905 break;

906 case R600::PRED_SETNE:

907 MO.setImm(R600::PRED_SETE);

908 break;

909 default:

910 return true;

911 }

912

914 switch (MO2.getReg()) {

915 case R600::PRED_SEL_ZERO:

916 MO2.setReg(R600::PRED_SEL_ONE);

917 break;

918 case R600::PRED_SEL_ONE:

919 MO2.setReg(R600::PRED_SEL_ZERO);

920 break;

921 default:

922 return true;

923 }

924 return false;

925}

926

928 std::vector &Pred,

929 bool SkipDead) const {

931}

932

935 int PIdx = MI.findFirstPredOperandIdx();

936

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

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

939 return true;

940 }

941

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

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

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

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

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

953 return true;

954 }

955

956 if (PIdx != -1) {

961 return true;

962 }

963

964 return false;

965}

966

970

973 unsigned *PredCost) const {

974 if (PredCost)

975 *PredCost = 2;

976 return 2;

977}

978

980 unsigned Channel) const {

981 assert(Channel == 0);

982 return RegIndex;

983}

984

986 switch (MI.getOpcode()) {

987 default: {

989 int OffsetOpIdx =

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

991

992

993 int RegOpIdx = OffsetOpIdx + 1;

994 int ChanOpIdx =

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

997 int DstOpIdx =

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

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

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

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

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

1006 } else {

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

1008 OffsetReg);

1009 }

1011 int ValOpIdx =

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

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

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

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

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

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

1020 } else {

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

1023 OffsetReg);

1024 }

1025 } else {

1026 return false;

1027 }

1028

1030 return true;

1031 }

1032 case R600::R600_EXTRACT_ELT_V2:

1033 case R600::R600_EXTRACT_ELT_V4:

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

1035 RI.getHWRegIndex(MI.getOperand(1).getReg()),

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

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

1038 break;

1039 case R600::R600_INSERT_ELT_V2:

1040 case R600::R600_INSERT_ELT_V4:

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

1042 RI.getHWRegIndex(MI.getOperand(1).getReg()),

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

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

1045 break;

1046 }

1047 MI.eraseFromParent();

1048 return true;

1049}

1050

1056

1059

1060 if (End == -1)

1061 return;

1062

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

1066 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 {

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 {

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

1199

1240

1241#define OPERAND_CASE(Label) \

1242 case Label: { \

1243 static const R600::OpName Ops[] = {Label##_X, Label##_Y, Label##_Z, \

1244 Label##_W}; \

1245 return Ops[Slot]; \

1246 }

1247

1249 switch (Op) {

1250 OPERAND_CASE(R600::OpName::update_exec_mask)

1267 default:

1269 }

1270}

1271

1272#undef OPERAND_CASE

1273

1276 const {

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

1278 unsigned Opcode;

1280 Opcode = R600::DOT4_r600;

1281 else

1282 Opcode = R600::DOT4_eg;

1290 static const R600::OpName Operands[14] = {

1291 R600::OpName::update_exec_mask,

1292 R600::OpName::update_pred,

1293 R600::OpName::write,

1294 R600::OpName::omod,

1295 R600::OpName::dst_rel,

1296 R600::OpName::clamp,

1297 R600::OpName::src0_neg,

1298 R600::OpName::src0_rel,

1299 R600::OpName::src0_abs,

1300 R600::OpName::src0_sel,

1301 R600::OpName::src1_neg,

1302 R600::OpName::src1_rel,

1303 R600::OpName::src1_abs,

1304 R600::OpName::src1_sel,

1305 };

1306

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

1311

1312 for (R600::OpName Operand : Operands) {

1317 }

1319 return MIB;

1320}

1321

1324 unsigned DstReg,

1327 R600::ALU_LITERAL_X);

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

1329 return MovImm;

1330}

1331

1334 unsigned DstReg, unsigned SrcReg) const {

1336}

1337

1339 R600::OpName Op) const {

1341}

1342

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

1345}

1346

1348 int64_t Imm) const {

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

1351 assert(MI.getOperand(Idx).isImm());

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

1353}

1354

1355

1356

1357

1358

1360 unsigned Flag) const {

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

1362 int FlagIndex = 0;

1363 if (Flag != 0) {

1364

1365

1366

1369 switch (Flag) {

1372 break;

1375 break;

1379 break;

1381 switch (SrcIdx) {

1382 case 0:

1384 break;

1385 case 1:

1387 break;

1388 case 2:

1390 break;

1391 }

1392 break;

1393

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

1396 "instructions.");

1397 (void)IsOP3;

1398 switch (SrcIdx) {

1399 case 0:

1401 break;

1402 case 1:

1404 break;

1405 }

1406 break;

1407

1408 default:

1409 FlagIndex = -1;

1410 break;

1411 }

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

1413 } else {

1415 assert(FlagIndex != 0 &&

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

1417 }

1418

1421 return FlagOp;

1422}

1423

1425 unsigned Flag) const {

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

1427 if (Flag == 0) {

1428 return;

1429 }

1436 } else {

1438 }

1439 } else {

1442 }

1443}

1444

1446 unsigned Flag) const {

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

1451 } else {

1453 unsigned InstFlags = FlagOp.getImm();

1454 InstFlags &= ~(Flag << (NUM_MO_FLAGS * SrcIdx));

1455 FlagOp.setImm(InstFlags);

1456 }

1457}

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Register const TargetRegisterInfo * TRI

static MCRegister 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)

Definition R600InstrInfo.cpp:615

static R600::OpName getSlotedOps(R600::OpName Op, unsigned Slot)

Definition R600InstrInfo.cpp:1248

static bool isBranch(unsigned Opcode)

Definition R600InstrInfo.cpp:632

static MachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB)

Definition R600InstrInfo.cpp:710

#define OPERAND_CASE(Label)

Definition R600InstrInfo.cpp:1241

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

Definition R600InstrInfo.cpp:340

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

Definition R600InstrInfo.cpp:368

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:481

static bool isPredicateSetter(unsigned Opcode)

Definition R600InstrInfo.cpp:605

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:445

static bool isJump(unsigned Opcode)

Definition R600InstrInfo.cpp:628

Interface definition for R600InstrInfo.

Provides R600 specific target descriptions.

AMDGPU R600 specific subclass of TargetSubtarget.

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

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.

unsigned getStackWidth(const MachineFunction &MF) const

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

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

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

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

MachineInstrBundleIterator< const MachineInstr > const_iterator

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

MachineInstrBundleIterator< MachineInstr > iterator

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

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

LLVM_ABI 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

Definition R600InstrInfo.cpp:174

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:1200

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

Definition R600InstrInfo.cpp:894

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

Definition R600InstrInfo.cpp:637

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

Add one of the MO_FLAG* flags to the operand at SrcIdx.

Definition R600InstrInfo.cpp:1424

bool usesAddressRegister(MachineInstr &MI) const

Definition R600InstrInfo.cpp:205

unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const

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

Definition R600InstrInfo.cpp:979

bool hasInstrModifiers(unsigned Opcode) const

Definition R600InstrInfo.cpp:114

R600InstrInfo(const R600Subtarget &)

Definition R600InstrInfo.cpp:31

bool isMov(unsigned Opcode) const

Definition R600InstrInfo.cpp:82

bool isRegisterLoad(const MachineInstr &MI) const

int getIndirectIndexBegin(const MachineFunction &MF) const

Definition R600InstrInfo.cpp:1142

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

Definition R600InstrInfo.cpp:880

bool usesTextureCache(unsigned Opcode) const

Definition R600InstrInfo.cpp:184

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:395

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

Definition R600InstrInfo.cpp:971

const TargetRegisterClass * getIndirectAddrRegClass() const

Definition R600InstrInfo.cpp:1072

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

Clear the specified flag on the instruction.

Definition R600InstrInfo.cpp:1445

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

Definition R600InstrInfo.cpp:1322

bool definesAddressRegister(MachineInstr &MI) const

Definition R600InstrInfo.cpp:209

unsigned getMaxAlusPerClause() const

Definition R600InstrInfo.cpp:1196

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

Definition R600InstrInfo.cpp:933

int getOperandIdx(const MachineInstr &MI, R600::OpName Op) const

Get the index of Op in the MachineInstr.

Definition R600InstrInfo.cpp:1338

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

Definition R600InstrInfo.cpp:74

bool canBeConsideredALU(const MachineInstr &MI) const

Definition R600InstrInfo.cpp:134

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

Definition R600InstrInfo.cpp:888

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:572

bool isVector(const MachineInstr &MI) const

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

Definition R600InstrInfo.cpp:34

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

Definition R600InstrInfo.cpp:765

bool mustBeLastInClause(unsigned Opcode) const

Definition R600InstrInfo.cpp:195

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

Definition R600InstrInfo.cpp:720

int getIndirectIndexEnd(const MachineFunction &MF) const

Definition R600InstrInfo.cpp:1174

bool isTransOnly(unsigned Opcode) const

Definition R600InstrInfo.cpp:152

DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const override

Definition R600InstrInfo.cpp:599

bool isReductionOp(unsigned opcode) const

Definition R600InstrInfo.cpp:93

bool isRegisterStore(const MachineInstr &MI) const

bool isCubeOp(unsigned opcode) const

Definition R600InstrInfo.cpp:97

bool isLDSInstr(unsigned Opcode) const

Definition R600InstrInfo.cpp:122

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

Reserve the registers that may be accessed using indirect addressing.

Definition R600InstrInfo.cpp:1051

void setImmOperand(MachineInstr &MI, R600::OpName Op, int64_t Imm) const

Helper function for setting instruction flag values.

Definition R600InstrInfo.cpp:1347

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

Definition R600InstrInfo.cpp:861

bool isPredicable(const MachineInstr &MI) const override

Definition R600InstrInfo.cpp:839

bool isPredicated(const MachineInstr &MI) const override

Definition R600InstrInfo.cpp:824

bool expandPostRAPseudo(MachineInstr &MI) const override

Definition R600InstrInfo.cpp:985

bool isLDSRetInstr(unsigned Opcode) const

Definition R600InstrInfo.cpp:130

int getSelIdx(unsigned Opcode, unsigned SrcIdx) const

Definition R600InstrInfo.cpp:224

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

Definition R600InstrInfo.cpp:1359

unsigned int getPredicationCost(const MachineInstr &) const override

Definition R600InstrInfo.cpp:967

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

Definition R600InstrInfo.cpp:1274

bool readsLDSSrcReg(const MachineInstr &MI) const

Definition R600InstrInfo.cpp:213

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:464

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:501

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

Definition R600InstrInfo.cpp:927

bool isALUInstr(unsigned Opcode) const

Definition R600InstrInfo.cpp:108

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

Definition R600InstrInfo.cpp:38

bool isVectorOnly(unsigned Opcode) const

Definition R600InstrInfo.cpp:162

bool isExport(unsigned Opcode) const

Definition R600InstrInfo.cpp:170

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

Definition R600InstrInfo.cpp:247

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

Definition R600InstrInfo.cpp:1332

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.

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

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

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 getHWRegChan(unsigned reg) const

get the HW encoding for a register's channel.

static unsigned getSubRegFromChannel(unsigned Channel)