LLVM: lib/CodeGen/TargetInstrInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

38

39using namespace llvm;

40

43 cl::desc("Disable hazard detection during preRA scheduling"));

44

46

52 return nullptr;

53

54 short RegClass = MCID.operands()[OpNum].RegClass;

55 if (MCID.operands()[OpNum].isLookupPtrRegClass())

56 return TRI->getPointerRegClass(MF, RegClass);

57

58

59 if (RegClass < 0)

60 return nullptr;

61

62

63 return TRI->getRegClass(RegClass);

64}

65

66

67

71}

72

73

74

77 unsigned Quantity) const {

78 for (unsigned i = 0; i < Quantity; ++i)

80}

81

85}

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

102 const char *Str,

104

105 bool AtInsnStart = true;

108 for (; *Str; ++Str) {

111 AtInsnStart = true;

113

114

115 AtInsnStart = false;

116 }

117

118 if (AtInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {

119 unsigned AddLength = MaxInstLength;

120 if (strncmp(Str, ".space", 6) == 0) {

121 char *EStr;

122 int SpaceSize;

123 SpaceSize = strtol(Str + 6, &EStr, 10);

124 SpaceSize = SpaceSize < 0 ? 0 : SpaceSize;

125 while (*EStr != '\n' && isSpace(static_cast<unsigned char>(*EStr)))

126 ++EStr;

127 if (*EStr == '\0' || *EStr == '\n' ||

128 isAsmComment(EStr, MAI))

129 AddLength = SpaceSize;

130 }

132 AtInsnStart = false;

133 }

134 }

135

137}

138

139

140

141void

145

146

149

150

152

153

154

157 if (MI->shouldUpdateAdditionalCallInfo())

160 }

161

162

166}

167

169 bool NewMI, unsigned Idx1,

170 unsigned Idx2) const {

173 if (HasDef && MI.getOperand(0).isReg())

174

175 return nullptr;

176

177 unsigned CommutableOpIdx1 = Idx1; (void)CommutableOpIdx1;

178 unsigned CommutableOpIdx2 = Idx2; (void)CommutableOpIdx2;

180 CommutableOpIdx1 == Idx1 && CommutableOpIdx2 == Idx2 &&

181 "TargetInstrInfo::CommuteInstructionImpl(): not commutable operands.");

182 assert(MI.getOperand(Idx1).isReg() && MI.getOperand(Idx2).isReg() &&

183 "This only knows how to commute register operands so far");

184

186 Register Reg1 = MI.getOperand(Idx1).getReg();

187 Register Reg2 = MI.getOperand(Idx2).getReg();

188 unsigned SubReg0 = HasDef ? MI.getOperand(0).getSubReg() : 0;

189 unsigned SubReg1 = MI.getOperand(Idx1).getSubReg();

190 unsigned SubReg2 = MI.getOperand(Idx2).getSubReg();

191 bool Reg1IsKill = MI.getOperand(Idx1).isKill();

192 bool Reg2IsKill = MI.getOperand(Idx2).isKill();

193 bool Reg1IsUndef = MI.getOperand(Idx1).isUndef();

194 bool Reg2IsUndef = MI.getOperand(Idx2).isUndef();

195 bool Reg1IsInternal = MI.getOperand(Idx1).isInternalRead();

196 bool Reg2IsInternal = MI.getOperand(Idx2).isInternalRead();

197

198

199 bool Reg1IsRenamable =

200 Reg1.isPhysical() ? MI.getOperand(Idx1).isRenamable() : false;

201 bool Reg2IsRenamable =

202 Reg2.isPhysical() ? MI.getOperand(Idx2).isRenamable() : false;

203

204

205 if (HasDef && Reg0 == Reg1 &&

206 MI.getDesc().getOperandConstraint(Idx1, MCOI::TIED_TO) == 0) {

207 Reg2IsKill = false;

208 Reg0 = Reg2;

209 SubReg0 = SubReg2;

210 } else if (HasDef && Reg0 == Reg2 &&

211 MI.getDesc().getOperandConstraint(Idx2, MCOI::TIED_TO) == 0) {

212 Reg1IsKill = false;

213 Reg0 = Reg1;

214 SubReg0 = SubReg1;

215 }

216

218 if (NewMI) {

219

222 } else {

223 CommutedMI = &MI;

224 }

225

226 if (HasDef) {

229 }

240

241

246 return CommutedMI;

247}

248

250 unsigned OpIdx1,

251 unsigned OpIdx2) const {

252

253

254

258 "Precondition violation: MI must be commutable.");

259 return nullptr;

260 }

262}

263

265 unsigned &ResultIdx2,

266 unsigned CommutableOpIdx1,

267 unsigned CommutableOpIdx2) {

270 ResultIdx1 = CommutableOpIdx1;

271 ResultIdx2 = CommutableOpIdx2;

273 if (ResultIdx2 == CommutableOpIdx1)

274 ResultIdx1 = CommutableOpIdx2;

275 else if (ResultIdx2 == CommutableOpIdx2)

276 ResultIdx1 = CommutableOpIdx1;

277 else

278 return false;

280 if (ResultIdx1 == CommutableOpIdx1)

281 ResultIdx2 = CommutableOpIdx2;

282 else if (ResultIdx1 == CommutableOpIdx2)

283 ResultIdx2 = CommutableOpIdx1;

284 else

285 return false;

286 } else

287

288

289 return (ResultIdx1 == CommutableOpIdx1 && ResultIdx2 == CommutableOpIdx2) ||

290 (ResultIdx1 == CommutableOpIdx2 && ResultIdx2 == CommutableOpIdx1);

291

292 return true;

293}

294

296 unsigned &SrcOpIdx1,

297 unsigned &SrcOpIdx2) const {

299 "TargetInstrInfo::findCommutedOpIndices() can't handle bundles");

300

303 return false;

304

305

306

307 unsigned CommutableOpIdx1 = MCID.getNumDefs();

308 unsigned CommutableOpIdx2 = CommutableOpIdx1 + 1;

310 CommutableOpIdx1, CommutableOpIdx2))

311 return false;

312

313 if (MI.getOperand(SrcOpIdx1).isReg() || MI.getOperand(SrcOpIdx2).isReg())

314

315 return false;

316 return true;

317}

318

320 if (MI.isTerminator()) return false;

321

322

323 if (MI.isBranch() && MI.isBarrier())

324 return true;

325 if (MI.isPredicable())

326 return true;

328}

329

332 bool MadeChange = false;

333

335 "TargetInstrInfo::PredicateInstruction() can't handle bundles");

336

338 if (MI.isPredicable())

339 return false;

340

341 for (unsigned j = 0, i = 0, e = MI.getNumOperands(); i != e; ++i) {

342 if (MCID.operands()[i].isPredicate()) {

344 if (MO.isReg()) {

346 MadeChange = true;

347 } else if (MO.isImm()) {

348 MO.setImm(Pred[j].getImm());

349 MadeChange = true;

350 } else if (MO.isMBB()) {

351 MO.setMBB(Pred[j].getMBB());

352 MadeChange = true;

353 }

354 ++j;

355 }

356 }

357 return MadeChange;

358}

359

363 size_t StartSize = Accesses.size();

365 oe = MI.memoperands_end();

366 o != oe; ++o) {

367 if ((*o)->isLoad() &&

368 isa_and_nonnull((*o)->getPseudoValue()))

370 }

371 return Accesses.size() != StartSize;

372}

373

377 size_t StartSize = Accesses.size();

379 oe = MI.memoperands_end();

380 o != oe; ++o) {

381 if ((*o)->isStore() &&

382 isa_and_nonnull((*o)->getPseudoValue()))

384 }

385 return Accesses.size() != StartSize;

386}

387

389 unsigned SubIdx, unsigned &Size,

393 if (!SubIdx) {

394 Size = TRI->getSpillSize(*RC);

396 return true;

397 }

398 unsigned BitSize = TRI->getSubRegIdxSize(SubIdx);

399

400 if (BitSize % 8)

401 return false;

402

403 int BitOffset = TRI->getSubRegIdxOffset(SubIdx);

404 if (BitOffset < 0 || BitOffset % 8)

405 return false;

406

407 Size = BitSize / 8;

409

410 assert(TRI->getSpillSize(*RC) >= (Offset + Size) && "bad subregister range");

411

414 }

415 return true;

416}

417

420 Register DestReg, unsigned SubIdx,

424 MI->substituteRegister(MI->getOperand(0).getReg(), DestReg, SubIdx, TRI);

426}

427

432}

433

439

440

444 "Instruction cannot be duplicated");

445

447}

448

449

450

453 unsigned FoldIdx) {

454 assert(TII.isCopyInstr(MI) && "MI must be a COPY instruction");

455 if (MI.getNumOperands() != 2)

456 return nullptr;

457 assert(FoldIdx<2 && "FoldIdx refers no nonexistent operand");

458

461

463 return nullptr;

464

467

469

472

475

477 return RC;

478

479

480 return nullptr;

481}

482

484

485std::pair<unsigned, unsigned>

487 switch (MI.getOpcode()) {

488 case TargetOpcode::STACKMAP:

489

490 return std::make_pair(0, StackMapOpers(&MI).getVarIdx());

491 case TargetOpcode::PATCHPOINT:

492

493

495 case TargetOpcode::STATEPOINT:

496

497 return std::make_pair(MI.getNumDefs(), StatepointOpers(&MI).getVarIdx());

498 default:

500 }

501}

502

506 unsigned StartIdx = 0;

507 unsigned NumDefs = 0;

508

509 std::tie(NumDefs, StartIdx) = TII.getPatchpointUnfoldableRange(MI);

510

511 unsigned DefToFoldIdx = MI.getNumOperands();

512

513

514

515 for (unsigned Op : Ops) {

516 if (Op < NumDefs) {

517 assert(DefToFoldIdx == MI.getNumOperands() && "Folding multiple defs");

518 DefToFoldIdx = Op;

519 } else if (Op < StartIdx) {

520 return nullptr;

521 }

522 if (MI.getOperand(Op).isTied())

523 return nullptr;

524 }

525

529

530

531 for (unsigned i = 0; i < StartIdx; ++i)

532 if (i != DefToFoldIdx)

533 MIB.add(MI.getOperand(i));

534

535 for (unsigned i = StartIdx, e = MI.getNumOperands(); i < e; ++i) {

537 unsigned TiedTo = e;

538 (void)MI.isRegTiedToDefOperand(i, &TiedTo);

539

541 assert(TiedTo == e && "Cannot fold tied operands");

542 unsigned SpillSize;

543 unsigned SpillOffset;

544

547 bool Valid =

548 TII.getStackSlotRange(RC, MO.getSubReg(), SpillSize, SpillOffset, MF);

549 if (!Valid)

551 MIB.addImm(StackMaps::IndirectMemRefOp);

552 MIB.addImm(SpillSize);

554 MIB.addImm(SpillOffset);

555 } else {

556 MIB.add(MO);

557 if (TiedTo < e) {

558 assert(TiedTo < NumDefs && "Bad tied operand");

559 if (TiedTo > DefToFoldIdx)

560 --TiedTo;

562 }

563 }

564 }

565 return NewMI;

566}

567

570

571 if (MI->getOperand(OpNo).isTied()) {

572 unsigned TiedTo = MI->findTiedOperandIdx(OpNo);

573 MI->untieRegOperand(OpNo);

574

576 }

577

579 TII.getFrameIndexOperands(NewOps, FI);

580 assert(!NewOps.empty() && "getFrameIndexOperands didn't create any operands");

581 MI->removeOperand(OpNo);

582 MI->insert(MI->operands_begin() + OpNo, NewOps);

583

584

585

586

591}

592

593

597 assert(MI.isInlineAsm() && "wrong opcode");

598 if (Ops.size() > 1)

599 return nullptr;

600 unsigned Op = Ops[0];

601 assert(Op && "should never be first operand");

602 assert(MI.getOperand(Op).isReg() && "shouldn't be folding non-reg operands");

603

604 if (MI.mayFoldInlineAsmRegOp(Op))

605 return nullptr;

606

608

610

611

619 }

623 }

630

631 return &NewMI;

632}

633

639 for (unsigned OpIdx : Ops)

642

644 assert(MBB && "foldMemoryOperand needs an inserted instruction");

646

647

648

649

650 int64_t MemSize = 0;

653

656 } else {

657 for (unsigned OpIdx : Ops) {

659

660 if (auto SubReg = MI.getOperand(OpIdx).getSubReg()) {

661 unsigned SubRegSize = TRI->getSubRegIdxSize(SubReg);

662 if (SubRegSize > 0 && !(SubRegSize % 8))

663 OpSize = SubRegSize / 8;

664 }

665

666 MemSize = std::max(MemSize, OpSize);

667 }

668 }

669

670 assert(MemSize && "Did not expect a zero-sized stack slot");

671

673

674 if (MI.getOpcode() == TargetOpcode::STACKMAP ||

675 MI.getOpcode() == TargetOpcode::PATCHPOINT ||

676 MI.getOpcode() == TargetOpcode::STATEPOINT) {

677

679 if (NewMI)

681 } else if (MI.isInlineAsm()) {

683 } else {

684

686 }

687

688 if (NewMI) {

690

693 "Folded a def to a non-store!");

696 "Folded a use to a non-load!");

702

703

704

706

707 return NewMI;

708 }

709

710

712 return nullptr;

713

715 if (!RC)

716 return nullptr;

717

720

724 else

726 return &*--Pos;

727}

728

734#ifndef NDEBUG

735 for (unsigned OpIdx : Ops)

736 assert(MI.getOperand(OpIdx).isUse() && "Folding load into def!");

737#endif

738

741

742

744 int FrameIndex = 0;

745

746 if ((MI.getOpcode() == TargetOpcode::STACKMAP ||

747 MI.getOpcode() == TargetOpcode::PATCHPOINT ||

748 MI.getOpcode() == TargetOpcode::STATEPOINT) &&

750

752 if (NewMI)

756 } else {

757

759 }

760

761 if (!NewMI)

762 return nullptr;

763

764

765 if (MI.memoperands_empty()) {

767 } else {

768

772 I != E; ++I) {

774 }

775 }

776 return NewMI;

777}

778

779

780

781

785 --CopyMI;

786

787 Register DstReg = MI->getOperand(0).getReg();

789 CopyMI->addOperand(MO);

790

791

792

793

794

795 if (MO.isKill() && TRI->regsOverlap(DstReg, MO.getReg()))

796 CopyMI->getOperand(CopyMI->getNumOperands() - 1).setIsKill(false);

797 }

798}

799

802 if (MI->allDefsAreDead()) {

803 MI->setDesc(get(TargetOpcode::KILL));

804 return;

805 }

806

809

810 bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg());

811 if (IdentityCopy || SrcMO.isUndef()) {

812

813

814 if (SrcMO.isUndef() || MI->getNumOperands() > 2) {

815

816

817 MI->setDesc(get(TargetOpcode::KILL));

818 return;

819 }

820

821 MI->eraseFromParent();

822 return;

823 }

824

829

830 if (MI->getNumOperands() > 2)

832 MI->eraseFromParent();

833}

834

840

841

842

846 MI1 = MRI.getUniqueVRegDef(Op1.getReg());

848 MI2 = MRI.getUniqueVRegDef(Op2.getReg());

849

850

852}

853

855 unsigned Opcode2) const {

856 return Opcode1 == Opcode2 || getInverseOpcode(Opcode1) == Opcode2;

857}

858

860 bool &Commuted) const {

865 unsigned Opcode = Inst.getOpcode();

866

867

868

871 if (Commuted)

873

874

875

876

877

878

879

880

881

887}

888

889

890

891

892

893

895 bool &Commuted) const {

900}

901

902

903

904

905

906

907

908

909

910

911

912

913

914

915

916

917

918

919

920

921

922

925 bool DoRegPressureReduce) const {

926 bool Commute;

928

929

930

931

932 if (Commute) {

935 } else {

938 }

939 return true;

940 }

941

942 return false;

943}

944

945

947 return false;

948}

949

953}

954

955std::pair<unsigned, unsigned>

961

962

963

964

965 if (AssocCommutRoot && AssocCommutPrev) {

968 }

969

970

971

972

973

975 "Incorrectly matched pattern");

976 unsigned AssocCommutOpcode = Root.getOpcode();

978 if (!AssocCommutRoot)

979 std::swap(AssocCommutOpcode, InverseOpcode);

980

981

982

983

984

985

986

987

988

989

990

991

992

993

994

995

996

997

998

999

1000

1001

1002

1004 default:

1007 if (!AssocCommutRoot && AssocCommutPrev)

1008 return {AssocCommutOpcode, InverseOpcode};

1009 if (AssocCommutRoot && !AssocCommutPrev)

1010 return {InverseOpcode, InverseOpcode};

1011 if (!AssocCommutRoot && !AssocCommutPrev)

1012 return {InverseOpcode, AssocCommutOpcode};

1013 break;

1015 if (!AssocCommutRoot && AssocCommutPrev)

1016 return {AssocCommutOpcode, InverseOpcode};

1017 if (AssocCommutRoot && !AssocCommutPrev)

1018 return {InverseOpcode, AssocCommutOpcode};

1019 if (!AssocCommutRoot && !AssocCommutPrev)

1020 return {InverseOpcode, InverseOpcode};

1021 break;

1023 if (!AssocCommutRoot && AssocCommutPrev)

1024 return {InverseOpcode, InverseOpcode};

1025 if (AssocCommutRoot && !AssocCommutPrev)

1026 return {AssocCommutOpcode, InverseOpcode};

1027 if (!AssocCommutRoot && !AssocCommutPrev)

1028 return {InverseOpcode, AssocCommutOpcode};

1029 break;

1031 if (!AssocCommutRoot && AssocCommutPrev)

1032 return {InverseOpcode, InverseOpcode};

1033 if (AssocCommutRoot && !AssocCommutPrev)

1034 return {InverseOpcode, AssocCommutOpcode};

1035 if (!AssocCommutRoot && !AssocCommutPrev)

1036 return {AssocCommutOpcode, InverseOpcode};

1037 break;

1038 }

1040}

1041

1042

1043

1044

1047 default:

1050 return {false, false};

1052 return {true, false};

1054 return {true, true};

1056 return {true, true};

1057 }

1058}

1059

1066 break;

1069 break;

1072 break;

1075 break;

1076 default:

1078 }

1079}

1080

1081

1082

1094

1100

1106

1108 MRI.constrainRegClass(RegA, RC);

1110 MRI.constrainRegClass(RegB, RC);

1112 MRI.constrainRegClass(RegX, RC);

1114 MRI.constrainRegClass(RegY, RC);

1116 MRI.constrainRegClass(RegC, RC);

1117

1118

1119

1120

1121 Register NewVR = MRI.createVirtualRegister(RC);

1122 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0));

1123

1125 bool KillA = OpA.isKill();

1126 bool KillX = OpX.isKill();

1127 bool KillY = OpY.isKill();

1128 bool KillNewVR = true;

1129

1131

1132 if (SwapPrevOperands) {

1135 }

1136

1137 unsigned PrevFirstOpIdx, PrevSecondOpIdx;

1138 unsigned RootFirstOpIdx, RootSecondOpIdx;

1145 break;

1151 break;

1157 break;

1163 break;

1164 default:

1166 }

1167

1168

1175 };

1176

1177

1179 buildMINoImplicit(*MF, MIMetadata(Prev), TII->get(NewPrevOpc), NewVR);

1181 unsigned Idx = MO.getOperandNo();

1182

1183 if (Idx == 0)

1184 continue;

1185 if (Idx == PrevFirstOpIdx)

1187 else if (Idx == PrevSecondOpIdx)

1189 else

1190 MIB1.add(MO);

1191 }

1193

1194 if (SwapRootOperands) {

1197 }

1198

1200 buildMINoImplicit(*MF, MIMetadata(Root), TII->get(NewRootOpc), RegC);

1202 unsigned Idx = MO.getOperandNo();

1203

1204 if (Idx == 0)

1205 continue;

1206 if (Idx == RootFirstOpIdx)

1208 else if (Idx == RootSecondOpIdx)

1210 else

1211 MIB2 = MIB2.add(MO);

1212 }

1214

1215

1216

1217

1219 MIB1->setFlags(IntersectedFlags);

1223

1224 MIB2->setFlags(IntersectedFlags);

1228

1230

1231

1236

1237

1238

1239

1240

1241

1242

1243

1244

1247}

1248

1255

1256

1261

1262

1264 return;

1265

1267 InstIdxForVirtReg);

1268}

1269

1272}

1273

1278

1279

1280 if (MI.getNumOperands() || MI.getOperand(0).isReg())

1281 return false;

1282 Register DefReg = MI.getOperand(0).getReg();

1283

1284

1285

1286

1287

1288 if (DefReg.isVirtual() && MI.getOperand(0).getSubReg() &&

1289 MI.readsVirtualRegister(DefReg))

1290 return false;

1291

1292

1293

1294

1295 int FrameIdx = 0;

1298 return true;

1299

1300

1301 if (MI.isNotDuplicable() || MI.mayStore() || MI.mayRaiseFPException() ||

1302 MI.hasUnmodeledSideEffects())

1303 return false;

1304

1305

1306

1307 if (MI.isInlineAsm())

1308 return false;

1309

1310

1311 if (MI.mayLoad() && MI.isDereferenceableInvariantLoad())

1312 return false;

1313

1314

1315

1317 if (!MO.isReg()) continue;

1319 if (Reg == 0)

1320 continue;

1321

1322

1323 if (Reg.isPhysical()) {

1324 if (MO.isUse()) {

1325

1326

1327

1328 if (MRI.isConstantPhysReg(Reg))

1329 return false;

1330 } else {

1331

1332 return false;

1333 }

1334 continue;

1335 }

1336

1337

1338

1339 if (MO.isDef() && Reg != DefReg)

1340 return false;

1341

1342

1343

1344

1345 if (MO.isUse())

1346 return false;

1347 }

1348

1349

1350 return true;

1351}

1352

1356 bool StackGrowsDown =

1358

1361

1363 return 0;

1364

1366

1367 if ((!StackGrowsDown && MI.getOpcode() == FrameSetupOpcode) ||

1368 (StackGrowsDown && MI.getOpcode() == FrameDestroyOpcode))

1369 SPAdj = -SPAdj;

1370

1371 return SPAdj;

1372}

1373

1374

1375

1376

1380

1381 if (MI.isTerminator() || MI.isPosition())

1382 return true;

1383

1384

1385 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)

1386 return true;

1387

1388

1389

1390

1391

1392

1396}

1397

1398

1399

1402}

1403

1404

1408

1410}

1411

1412

1416}

1417

1418

1423}

1424

1425

1432 Width, TRI) ||

1433 BaseOps.size() != 1)

1434 return false;

1435 BaseOp = BaseOps.front();

1436 return true;

1437}

1438

1439

1440

1441

1442

1443std::optional

1445 SDNode *DefNode, unsigned DefIdx,

1446 SDNode *UseNode, unsigned UseIdx) const {

1447 if (!ItinData || ItinData->isEmpty())

1448 return std::nullopt;

1449

1451 return std::nullopt;

1452

1457 return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);

1458}

1459

1462 if (!ItinData || ItinData->isEmpty())

1463 return 1;

1464

1465 if (N->isMachineOpcode())

1466 return 1;

1467

1469}

1470

1471

1472

1473

1474

1477 if (!ItinData || ItinData->isEmpty())

1478 return 1;

1479

1480 unsigned Class = MI.getDesc().getSchedClass();

1482 if (UOps >= 0)

1483 return UOps;

1484

1485

1486

1487 return 1;

1488}

1489

1490

1493 if (DefMI.isTransient())

1494 return 0;

1495 if (DefMI.mayLoad())

1499 return 1;

1500}

1501

1503 return 0;

1504}

1505

1508 unsigned *PredCost) const {

1509

1510

1511 if (!ItinData)

1512 return MI.mayLoad() ? 2 : 1;

1513

1515}

1516

1519 unsigned DefIdx) const {

1521 if (!ItinData || ItinData->isEmpty())

1522 return false;

1523

1524 unsigned DefClass = DefMI.getDesc().getSchedClass();

1525 std::optional DefCycle =

1527 return DefCycle && DefCycle <= 1U;

1528}

1529

1531

1532

1533

1534

1536 return false;

1537

1538

1539

1541 if (SectionPrefix &&

1542 (*SectionPrefix == "unlikely" || *SectionPrefix == "unknown")) {

1543 return false;

1544 }

1545

1546 return true;

1547}

1548

1549std::optional

1556 bool OffsetIsScalable;

1557

1558

1559

1562

1564 Register DestReg = DestSrc->Destination->getReg();

1565

1566

1567

1568

1569

1570

1571 if (Reg == DestReg)

1573

1574

1575 return std::nullopt;

1577 Register SrcReg = RegImm->Reg;

1578 Offset = RegImm->Imm;

1581 } else if (MI.hasOneMemOperand()) {

1582

1583

1584

1589

1590

1591

1592 if (!PSV || PSV->mayAlias(&MFI))

1593 return std::nullopt;

1594

1596 if (TII->getMemOperandWithOffset(MI, BaseOp, Offset, OffsetIsScalable,

1598 return std::nullopt;

1599

1600

1601 if (OffsetIsScalable)

1602 return std::nullopt;

1603

1604

1605

1606

1607

1608

1609

1610 if (MI.getNumExplicitDefs() != 1)

1611 return std::nullopt;

1612

1613

1614

1617 Ops.push_back(dwarf::DW_OP_deref_size);

1619 : ~UINT64_C(0));

1622 }

1623

1624 return std::nullopt;

1625}

1626

1627

1629

1635 return 0;

1636 }

1637

1638

1639

1641}

1642

1643

1644

1647 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {

1648 unsigned DefClass = DefMI.getDesc().getSchedClass();

1649 unsigned UseClass = UseMI.getDesc().getSchedClass();

1650 return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);

1651}

1652

1656 assert((MI.isRegSequence() ||

1657 MI.isRegSequenceLike()) && "Instruction do not have the proper type");

1658

1659 if (MI.isRegSequence())

1661

1662

1663

1664 assert(DefIdx == 0 && "REG_SEQUENCE only has one def");

1665 for (unsigned OpIdx = 1, EndOpIdx = MI.getNumOperands(); OpIdx != EndOpIdx;

1666 OpIdx += 2) {

1669 continue;

1672 "One of the subindex of the reg_sequence is not an immediate");

1673

1675 (unsigned)MOSubIdx.getImm()));

1676 }

1677 return true;

1678}

1679

1683 assert((MI.isExtractSubreg() ||

1684 MI.isExtractSubregLike()) && "Instruction do not have the proper type");

1685

1686 if (MI.isExtractSubreg())

1688

1689

1690

1691 assert(DefIdx == 0 && "EXTRACT_SUBREG only has one def");

1694 return false;

1697 "The subindex of the extract_subreg is not an immediate");

1698

1702 return true;

1703}

1704

1708 assert((MI.isInsertSubreg() ||

1709 MI.isInsertSubregLike()) && "Instruction do not have the proper type");

1710

1711 if (MI.isInsertSubreg())

1713

1714

1715

1716 assert(DefIdx == 0 && "INSERT_SUBREG only has one def");

1719 if (MOInsertedReg.isUndef())

1720 return false;

1723 "One of the subindex of the reg_sequence is not an immediate");

1724 BaseReg.Reg = MOBaseReg.getReg();

1726

1727 InsertedReg.Reg = MOInsertedReg.getReg();

1730 return true;

1731}

1732

1733

1737

1738 if (MI.isInlineAsm())

1739 return "";

1740

1741 std::string Flags;

1743

1745

1746 unsigned ExtraInfo = Op.getImm();

1747 bool First = true;

1750 OS << " ";

1753 }

1754

1755 return Flags;

1756 }

1757

1758 int FlagIdx = MI.findInlineAsmFlagIdx(OpIdx);

1759 if (FlagIdx < 0 || (unsigned)FlagIdx != OpIdx)

1760 return "";

1761

1762 assert(Op.isImm() && "Expected flag operand to be an immediate");

1763

1764 unsigned Flag = Op.getImm();

1766 OS << F.getKindName();

1767

1768 unsigned RCID;

1769 if (F.isImmKind() && F.isMemKind() && F.hasRegClassConstraint(RCID)) {

1770 if (TRI) {

1771 OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID));

1772 } else

1773 OS << ":RC" << RCID;

1774 }

1775

1776 if (F.isMemKind()) {

1779 }

1780

1781 unsigned TiedTo;

1782 if (F.isUseOperandTiedToDef(TiedTo))

1783 OS << " tiedto:$" << TiedTo;

1784

1785 if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() || F.isRegUseKind()) &&

1786 F.getRegMayBeFolded())

1787 OS << " foldable";

1788

1789 return Flags;

1790}

1791

1793

1795 Function &F, std::vectoroutliner::Candidate &Candidates) const {

1796

1797

1798

1799

1803 F.addFnAttr(ParentFn.getFnAttribute("target-features"));

1806

1807

1809 return C.getMF()->getFunction().hasFnAttribute(Attribute::NoUnwind);

1810 }))

1811 F.addFnAttr(Attribute::NoUnwind);

1812}

1813

1817 unsigned Flags) const {

1819

1820

1821

1822 if (MI.isCFIInstruction())

1823

1825

1826

1827 if (MI.isInlineAsm())

1829

1830

1831 if (MI.isLabel())

1833

1834

1835 if (MI.isDebugInstr())

1837

1838

1839 switch (MI.getOpcode()) {

1840 case TargetOpcode::IMPLICIT_DEF:

1841 case TargetOpcode::KILL:

1842 case TargetOpcode::LIFETIME_START:

1843 case TargetOpcode::LIFETIME_END:

1845 default:

1846 break;

1847 }

1848

1849

1850 if (MI.isTerminator()) {

1851

1852 if (MI.getParent()->succ_empty())

1854

1855

1858 }

1859

1860

1861

1862

1863

1864

1865

1866

1867

1868

1869

1870

1871

1873

1874

1875

1876

1877 assert(!MOP.isTargetIndex() && "This isn't used quite yet!");

1878

1879

1880 assert(!MOP.isCFIIndex() && "CFI instructions handled elsewhere!");

1881

1882

1883 assert(!MOP.isFI() && "FrameIndex instructions should be gone by now!");

1884

1885 if (MOP.isMBB() || MOP.isBlockAddress() || MOP.isCPI() || MOP.isJTI())

1887 }

1888

1889

1891}

1892

1894 unsigned &Flags) const {

1895

1896

1899 return true;

1900

1901 if (First->getOpcode() == TargetOpcode::FENTRY_CALL ||

1902 First->getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)

1903 return false;

1904

1905

1906

1908 if (Last->getOpcode() == TargetOpcode::PATCHABLE_RET ||

1909 Last->getOpcode() == TargetOpcode::PATCHABLE_TAIL_CALL)

1910 return false;

1911

1914 if (Last->getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_EXIT ||

1915 Last->getOpcode() == TargetOpcode::PATCHABLE_TAIL_CALL)

1916 return false;

1917 }

1918 return true;

1919}

1920

1922 return MI->isCall() || MI->hasUnmodeledSideEffects() ||

1923 (MI->hasOrderedMemoryRef() && MI->isDereferenceableInvariantLoad());

1924}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder & UseMI

MachineInstrBuilder MachineInstrBuilder & DefMI

SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Analysis containing CSE Info

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

This file contains constants used for implementing Dwarf debug support.

static Function * getFunction(Constant *C)

const HexagonInstrInfo * TII

unsigned const TargetRegisterInfo * TRI

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

uint64_t IntrinsicInst * II

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

static bool isAsmComment(const char *Str, const MCAsmInfo &MAI)

static void transferImplicitOperands(MachineInstr *MI, const TargetRegisterInfo *TRI)

transferImplicitOperands - MI is a pseudo-instruction, and the lowered replacement instructions immed...

static std::pair< bool, bool > mustSwapOperands(unsigned Pattern)

static const TargetRegisterClass * canFoldCopy(const MachineInstr &MI, const TargetInstrInfo &TII, unsigned FoldIdx)

static void foldInlineAsmMemOperand(MachineInstr *MI, unsigned OpNo, int FI, const TargetInstrInfo &TII)

static cl::opt< bool > DisableHazardRecognizer("disable-sched-hazard", cl::Hidden, cl::init(false), cl::desc("Disable hazard detection during preRA scheduling"))

static MachineInstr * foldPatchpoint(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, const TargetInstrInfo &TII)

This file describes how to lower LLVM code to machine code.

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

size_t size() const

size - Get the array size.

static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)

Append Ops with operations to apply the Offset.

static DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)

Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...

static DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)

Prepend DIExpr with the given opcodes and optionally turn it into a stack value.

This class represents an Operation in the Expression.

bool isLittleEndian() const

Layout endianness...

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

std::optional< StringRef > getSectionPrefix() const

Get the section prefix for this function.

Attribute getFnAttribute(Attribute::AttrKind Kind) const

Return the attribute for the given attribute kind.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

bool hasSection() const

Check if this global has a custom object file section.

static std::vector< StringRef > getExtraInfoNames(unsigned ExtraInfo)

static StringRef getMemConstraintName(ConstraintCode C)

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

std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const

Return the cycle for the given class and operand.

unsigned getStageLatency(unsigned ItinClassIndx) const

Return the total stage latency of the given class.

std::optional< unsigned > getOperandLatency(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const

Compute and return the use operand latency of a given itinerary class and operand index if the value ...

const InstrItinerary * Itineraries

Array of itineraries selected.

bool isEmpty() const

Returns true if there are no itineraries.

TypeSize getValue() const

This class is intended to be used as a base class for asm properties and features specific to the tar...

virtual unsigned getMaxInstLength(const MCSubtargetInfo *STI=nullptr) const

Returns the maximum possible encoded instruction size in bytes.

StringRef getCommentString() const

const char * getSeparatorString() const

Instances of this class represent a single low-level machine instruction.

Describe properties that are true of each instruction in the target description file.

unsigned getSchedClass() const

Return the scheduling class for this instruction.

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

ArrayRef< MCOperandInfo > operands() const

unsigned getNumDefs() const

Return the number of MachineOperands that are register definitions.

bool isCommutable() const

Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

instr_iterator instr_begin()

instr_iterator insert(instr_iterator I, MachineInstr *M)

Insert MI into the instruction list before I, possibly inside a bundle.

iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)

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

succ_iterator succ_begin()

void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())

Add Succ as a successor of this MachineBasicBlock.

void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)

Remove successor from the successors list of this MachineBasicBlock.

iterator getLastNonDebugInstr(bool SkipPseudoOp=true)

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

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

unsigned getCallFrameSize() const

Return the call frame size on entry to this basic block.

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

bool isImmutableObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to an immutable object.

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

int64_t getObjectOffset(int ObjectIdx) const

Return the assigned stack offset of the specified object from the incoming stack pointer.

bool hasProperty(Property P) const

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineInstr & cloneMachineInstrBundle(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig)

Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore.

MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImplicit=false)

CreateMachineInstr - Allocate a new MachineInstr.

MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)

getMachineMemOperand - Allocate a new MachineMemOperand.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineFunctionProperties & getProperties() const

Get the function properties.

void eraseAdditionalCallInfo(const MachineInstr *MI)

Following functions update call site info.

MachineInstr * CloneMachineInstr(const MachineInstr *Orig)

Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addFrameIndex(int Idx) const

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

Add a new virtual register operand.

const MachineInstrBuilder & setPCSections(MDNode *MD) const

const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const

Copy all the implicit operands from OtherMI onto this one.

MachineInstr * getInstr() const

If conversion operators fail, use this method to get the MachineInstr explicitly.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

void setFlags(unsigned flags)

unsigned getNumOperands() const

Retuns the total number of operands.

void setDebugInstrNum(unsigned Num)

Set instruction number of this MachineInstr.

mmo_iterator memoperands_end() const

Access to memory operands of the instruction.

iterator_range< mop_iterator > explicit_operands()

unsigned peekDebugInstrNum() const

Examine the instruction number of this MachineInstr.

void setMemRefs(MachineFunction &MF, ArrayRef< MachineMemOperand * > MemRefs)

Assign this MachineInstr's memory reference descriptor list.

bool mayLoad(QueryType Type=AnyInBundle) const

Return true if this instruction could possibly read memory.

bool isCFIInstruction() const

bool isNotDuplicable(QueryType Type=AnyInBundle) const

Return true if this instruction cannot be safely duplicated.

void clearFlag(MIFlag Flag)

clearFlag - Clear a MI flag.

void tieOperands(unsigned DefIdx, unsigned UseIdx)

Add a tie between the register operands at DefIdx and UseIdx.

mmo_iterator memoperands_begin() const

Access to memory operands of the instruction.

void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI)

Clone another MachineInstr's pre- and post- instruction symbols and replace ours with it.

bool isIdenticalTo(const MachineInstr &Other, MICheckType Check=CheckDefs) const

Return true if this instruction is identical to Other.

const MachineFunction * getMF() const

Return the function that contains the basic block that this instruction belongs to.

ArrayRef< MachineMemOperand * > memoperands() const

Access to memory operands of the instruction.

bool mayStore(QueryType Type=AnyInBundle) const

Return true if this instruction could possibly modify memory.

const MachineOperand & getOperand(unsigned i) const

uint32_t getFlags() const

Return the MI flags bitvector.

bool canFoldAsLoad(QueryType Type=IgnoreBundle) const

Return true for instructions that can be folded as memory operands in other instructions.

const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const

Compute the static register class constraint for operand OpIdx.

void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)

Add a MachineMemOperand to the machine instruction.

A description of a memory reference used in the backend.

LocationSize getSize() const

Return the size in bytes of the memory reference.

const PseudoSourceValue * getPseudoValue() const

Flags

Flags values. These may be or'd together.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

This class contains meta information specific to a module.

MachineOperand class - Representation of each machine instruction operand.

void setSubReg(unsigned subReg)

unsigned getSubReg() const

void setIsInternalRead(bool Val=true)

void setImm(int64_t immVal)

void setIsRenamable(bool Val=true)

bool isReg() const

isReg - Tests if this is a MO_Register operand.

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 isRenamable() const

isRenamable - Returns true if this register may be renamed, i.e.

void setMBB(MachineBasicBlock *MBB)

void setIsUndef(bool Val=true)

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)

bool isMBB() const

isMBB - Tests if this is a MO_MachineBasicBlock operand.

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

const TargetRegisterClass * getRegClass(Register Reg) const

Return the register class of the specified virtual register.

MI-level patchpoint operands.

Special value supplied for machine level alias analysis.

virtual bool mayAlias(const MachineFrameInfo *) const

Return true if the memory pointed to by this PseudoSourceValue can ever alias an LLVM IR Value.

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

constexpr bool isPhysical() const

Return true if the specified register number is in the physical register namespace.

Represents one node in the SelectionDAG.

bool isMachineOpcode() const

Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.

unsigned getMachineOpcode() const

This may only be called if isMachineOpcode returns true.

ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...

HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...

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

void push_back(const T &Elt)

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

MI-level stackmap operands.

MI-level Statepoint operands.

StringRef - Represent a constant reference to a string, i.e.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Information about stack frame layout on the target.

StackDirection getStackGrowthDirection() const

getStackGrowthDirection - Return the direction the stack grows

int alignSPAdjust(int SPAdj) const

alignSPAdjust - This method aligns the stack adjustment to the correct alignment.

virtual ~PipelinerLoopInfo()

TargetInstrInfo - Interface to description of machine instruction set.

virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const

Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...

virtual MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const

Target-dependent implementation for foldMemoryOperand.

virtual bool hasLowDefLatency(const TargetSchedModel &SchedModel, const MachineInstr &DefMI, unsigned DefIdx) const

Compute operand latency of a def of 'Reg'.

virtual void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2, MachineInstr &NewMI1, MachineInstr &NewMI2) const

This is an architecture-specific helper function of reassociateOps.

virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, const MachineInstr &MI) const

Return the number of u-operations the given machine instruction will be decoded to on the target cpu.

virtual int getSPAdjust(const MachineInstr &MI) const

Returns the actual stack pointer adjustment made by an instruction as part of a call sequence.

virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const

Load the specified register of the given register class from the specified stack frame index.

virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const

Delete the instruction OldInst and everything after it, replacing it with an unconditional branch to ...

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

Convert the instruction into a predicated instruction.

bool areOpcodesEqualOrInverse(unsigned Opcode1, unsigned Opcode2) const

Return true when \P Opcode1 or its inversion is equal to \P Opcode2.

virtual outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MIT, unsigned Flags) const

Target-dependent implementation for getOutliningTypeImpl.

virtual bool getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const

Target-dependent implementation of getInsertSubregInputs.

outliner::InstrType getOutliningType(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MIT, unsigned Flags) const

Returns how or if MIT should be outlined.

virtual bool isThroughputPattern(unsigned Pattern) const

Return true when a code sequence can improve throughput.

virtual std::pair< unsigned, unsigned > getPatchpointUnfoldableRange(const MachineInstr &MI) const

For a patchpoint, stackmap, or statepoint intrinsic, return the range of operands which can't be fold...

virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const

Store the specified register of the given register class to the specified stack frame index.

virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const

Returns true iff the routine could find two commutable operands in the given machine instruction.

virtual void mergeOutliningCandidateAttributes(Function &F, std::vector< outliner::Candidate > &Candidates) const

Optional target hook to create the LLVM IR attributes for the outlined function.

bool isUnpredicatedTerminator(const MachineInstr &MI) const

Returns true if the instruction is a terminator instruction that has not been predicated.

virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const

Insert a noop into the instruction stream at the specified point.

bool isFrameInstr(const MachineInstr &I) const

Returns true if the argument is a frame pseudo instruction.

virtual bool getRegSequenceLikeInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const

Target-dependent implementation of getRegSequenceInputs.

virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, unsigned &Size, unsigned &Offset, const MachineFunction &MF) const

Compute the size in bytes and offset within a stack slot of a spilled register or subregister.

virtual ScheduleHazardRecognizer * CreateTargetMIHazardRecognizer(const InstrItineraryData *, const ScheduleDAGMI *DAG) const

Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...

virtual bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const

If the specified machine instruction has a store to a stack slot, return true along with the FrameInd...

virtual bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const

Return true when \P Inst has reassociable operands in the same \P MBB.

virtual unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI, const TargetSubtargetInfo *STI=nullptr) const

Measure the specified inline asm to determine an approximation of its length.

virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstIdxForVirtReg) const

When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...

virtual std::optional< ParamLoadedValue > describeLoadedValue(const MachineInstr &MI, Register Reg) const

Produce the expression describing the MI loading a value into the physical register Reg.

void lowerCopy(MachineInstr *MI, const TargetRegisterInfo *TRI) const

This function defines the logic to lower COPY instruction to target specific instruction(s).

virtual Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const

If the specified machine instruction is a direct load from a stack slot, return the virtual or physic...

MachineInstr * foldMemoryOperand(MachineInstr &MI, ArrayRef< unsigned > Ops, int FI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const

Attempt to fold a load or store of the specified stack slot into the specified machine instruction fo...

virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const

Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...

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

Insert branch code into the end of the specified MachineBasicBlock.

unsigned getCallFrameSetupOpcode() const

These methods return the opcode of the frame setup/destroy instructions if they exist (-1 otherwise).

virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const

Return true when there is potentially a faster code sequence for an instruction chain ending in Root.

virtual MCInst getNop() const

Return the noop instruction to use for a noop.

unsigned getCallFrameSizeAt(MachineInstr &MI) const

virtual MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const

Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore.

std::pair< unsigned, unsigned > getReassociationOpcodes(unsigned Pattern, const MachineInstr &Root, const MachineInstr &Prev) const

Reassociation of some instructions requires inverse operations (e.g.

virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const

Optional target hook that returns true if MBB is safe to outline from, and returns any target-specifi...

virtual void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const

The returned array encodes the operand index for each parameter because the operands may be commuted;...

int64_t getFrameTotalSize(const MachineInstr &I) const

Returns the total frame size, which is made up of the space set up inside the pair of frame start-sto...

MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const

This method commutes the operands of the given machine instruction MI.

virtual std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, SDNode *UseNode, unsigned UseIdx) const

virtual bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert=false) const

Return true when \P Inst is both associative and commutative.

virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const

Re-issue the specified 'original' instruction at the specific location targeting a new destination re...

virtual std::optional< unsigned > getInverseOpcode(unsigned Opcode) const

Return the inverse operation opcode if it exists for \P Opcode (e.g.

virtual void insertNoops(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Quantity) const

Insert noops into the instruction stream at the specified point.

unsigned getCallFrameDestroyOpcode() const

int64_t getFrameSize(const MachineInstr &I) const

Returns size of the frame associated with the given frame instruction.

virtual bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const

For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...

virtual bool isPredicated(const MachineInstr &MI) const

Returns true if the instruction is already predicated.

bool getInsertSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const

Build the equivalent inputs of a INSERT_SUBREG for the given MI and DefIdx.

virtual ~TargetInstrInfo()

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

Compute the instruction latency of a given instruction.

virtual bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1, const MachineRegisterInfo *MRI=nullptr) const

Return true if two machine instructions would produce identical values.

std::optional< DestSourcePair > isCopyInstr(const MachineInstr &MI) const

If the specific machine instruction is a instruction that moves/copies value from one register to ano...

bool isReassociationCandidate(const MachineInstr &Inst, bool &Commuted) const

Return true if the input \P Inst is part of a chain of dependent ops that are suitable for reassociat...

virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const

Test if the given instruction should be considered a scheduling boundary.

virtual bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const

Get zero or more base operands and the byte offset of an instruction that reads/writes memory.

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

Emit instructions to copy a pair of physical registers.

virtual unsigned getPredicationCost(const MachineInstr &MI) const

virtual CombinerObjective getCombinerObjective(unsigned Pattern) const

Return the objective of a combiner pattern.

virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const

This method commutes the operands of the given machine instruction MI.

virtual bool isFunctionSafeToSplit(const MachineFunction &MF) const

Return true if the function is a viable candidate for machine function splitting.

virtual MachineTraceStrategy getMachineCombinerTraceStrategy() const

Return a strategy that MachineCombiner must use when creating traces.

bool getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const

Build the equivalent inputs of a REG_SEQUENCE for the given MI and DefIdx.

virtual bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const

If the specified machine instruction has a load from a stack slot, return true along with the FrameIn...

virtual bool isGlobalMemoryObject(const MachineInstr *MI) const

Returns true if MI is an instruction we are unable to reason about (like a call or something with unm...

virtual std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const

If the specific machine instruction is an instruction that adds an immediate value and a register,...

unsigned defaultDefLatency(const MCSchedModel &SchedModel, const MachineInstr &DefMI) const

Return the default expected latency for a def based on its opcode.

void reassociateOps(MachineInstr &Root, MachineInstr &Prev, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, ArrayRef< unsigned > OperandIndices, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const

Attempt to reassociate \P Root and \P Prev according to \P Pattern to reduce critical path length.

static const unsigned CommuteAnyOperandIndex

virtual bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const

Return true when \P Inst has reassociable sibling.

virtual std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const

virtual bool isHighLatencyDef(int opc) const

Return true if this opcode has high latency to its result.

static bool fixCommutedOpIndices(unsigned &ResultIdx1, unsigned &ResultIdx2, unsigned CommutableOpIdx1, unsigned CommutableOpIdx2)

Assigns the (CommutableOpIdx1, CommutableOpIdx2) pair of commutable operand indices to (ResultIdx1,...

bool getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const

Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.

virtual bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const

Target-dependent implementation of getExtractSubregInputs.

bool usePreRAHazardRecognizer() const

Provide a global flag for disabling the PreRA hazard recognizer that targets may choose to honor.

virtual const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) const

Given a machine instruction descriptor, returns the register class constraint for OpNum,...

bool getMemOperandWithOffset(const MachineInstr &MI, const MachineOperand *&BaseOp, int64_t &Offset, bool &OffsetIsScalable, const TargetRegisterInfo *TRI) const

Get the base operand and byte offset of an instruction that reads/writes memory.

Register getStackPointerRegisterToSaveRestore() const

If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...

This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...

const Triple & getTargetTriple() const

bool contains(Register Reg) const

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

bool hasSubClassEq(const TargetRegisterClass *RC) const

Returns true if RC is a sub-class of or equal to this class.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

Provide an instruction scheduling machine model to CodeGen passes.

const InstrItineraryData * getInstrItineraries() const

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual const TargetRegisterInfo * getRegisterInfo() const

getRegisterInfo - If register information is available, return it.

virtual const TargetFrameLowering * getFrameLowering() const

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetLowering * getTargetLowering() const

bool isOSDarwin() const

Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, XROS, or DriverKit).

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

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

@ Tail

Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...

@ C

The default llvm calling convention, compatible with C.

@ Define

Register definition.

initializer< Ty > init(const Ty &Val)

InstrType

Represents how an instruction should be mapped by the outliner.

This is an optimization pass for GlobalISel generic memory operations.

MachineTraceStrategy

Strategies for selecting traces.

@ TS_MinInstrCount

Select the trace through a block that has the fewest instructions.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

std::pair< MachineOperand, DIExpression * > ParamLoadedValue

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

auto reverse(ContainerTy &&C)

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

CombinerObjective

The combiner's goal may differ based on which pattern it is attempting to optimize.

VirtRegInfo AnalyzeVirtRegInBundle(MachineInstr &MI, Register Reg, SmallVectorImpl< std::pair< MachineInstr *, unsigned > > *Ops=nullptr)

AnalyzeVirtRegInBundle - Analyze how the current instruction or bundle uses a virtual register.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

unsigned getKillRegState(bool B)

DWARFExpression::Operation Op

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

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

Implement std::swap in terms of BitVector swap.

Machine model for scheduling, bundling, and heuristics.

static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.

A pair composed of a pair of a register and a sub-register index, and another sub-register index.

A pair composed of a register and a sub-register index.

VirtRegInfo - Information about a virtual register used by a set of operands.

bool Reads

Reads - One of the operands read the virtual register.

bool Writes

Writes - One of the operands writes the virtual register.

An individual sequence of instructions to be replaced with a call to an outlined function.

MachineFunction * getMF() const