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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

104#include

105#include

106#include

107#include

108#include

109

110using namespace llvm;

111using namespace PatternMatch;

112

113#define DEBUG_TYPE "isel"

114

115STATISTIC(NumFastIselSuccessIndependent, "Number of insts selected by "

116 "target-independent selector");

117STATISTIC(NumFastIselSuccessTarget, "Number of insts selected by "

118 "target-specific selector");

119STATISTIC(NumFastIselDead, "Number of dead insts removed on failure");

120

121

122

125 "local values should be cleared after finishing a BB");

126

127

128

129

134}

135

137

140

141

142 return false;

143

145 return false;

146

147

150 I != E; ++I) {

154 }

155 return true;

156}

157

158

159

163 if (!MO.isReg())

164 continue;

165 if (MO.isDef()) {

166 if (RegDef)

168 RegDef = MO.getReg();

169 } else if (MO.getReg().isVirtual()) {

170

172 }

173 }

174 return RegDef;

175}

176

180 if (P.second == DefReg)

181 return true;

182 return false;

183}

184

185void FastISel::flushLocalValueMap() {

186

187

189

191 ++FirstNonValue;

192

200 if (!DefReg)

201 continue;

203 continue;

208 LLVM_DEBUG(dbgs() << "removing dead local value materialization"

209 << LocalMI);

210 LocalMI.eraseFromParent();

211 }

212 }

213

215

216

217

218

219

220

221

222

223

227 if (FirstLocalValue != FirstNonValue && !FirstLocalValue->getDebugLoc())

228 FirstLocalValue->setDebugLoc(FirstNonValue->getDebugLoc());

229 }

230 }

231

236}

237

240

243

244

245

246

249

250 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)

252 else

254 }

255

256

258 if (Reg)

259 return Reg;

260

261

262

263 if (isa(V) &&

264 (!isa(V) ||

267

269

270

271

272 Reg = materializeRegForValue(V, VT);

273

275

276 return Reg;

277}

278

279Register FastISel::materializeConstant(const Value *V, MVT VT) {

281 if (const auto *CI = dyn_cast(V)) {

282 if (CI->getValue().getActiveBits() <= 64)

284 } else if (isa(V))

286 else if (isa(V))

287

288

289 Reg =

291 else if (const auto *CF = dyn_cast(V)) {

292 if (CF->isNullValue())

294 else

295

297

298 if (!Reg) {

299

300 const APFloat &Flt = CF->getValueAPF();

303 APSInt SIntVal(IntBitWidth, false);

304 bool isExact;

306 if (isExact) {

308 getRegForValue(ConstantInt::get(V->getContext(), SIntVal));

309 if (IntegerReg)

311 IntegerReg);

312 }

313 }

314 } else if (const auto *Op = dyn_cast(V)) {

316 if (!isa(Op) ||

318 return 0;

320 } else if (isa(V)) {

323 TII.get(TargetOpcode::IMPLICIT_DEF), Reg);

324 }

325 return Reg;

326}

327

328

329

330

331Register FastISel::materializeRegForValue(const Value *V, MVT VT) {

333

334 if (isa(V))

336

337

338

339 if (!Reg)

340 Reg = materializeConstant(V, VT);

341

342

343

344 if (Reg) {

347 }

348 return Reg;

349}

350

352

353

354

355

358 return I->second;

360}

361

363 if (!isa(I)) {

365 return;

366 }

367

369 if (!AssignedReg)

370

371 AssignedReg = Reg;

372 else if (Reg != AssignedReg) {

373

374 for (unsigned i = 0; i < NumRegs; i++) {

377 }

378

379 AssignedReg = Reg;

380 }

381}

382

385 if (!IdxN)

386

388

389

390 EVT IdxVT = EVT::getEVT(Idx->getType(), false);

391 if (IdxVT.bitsLT(PtrVT)) {

393 } else if (IdxVT.bitsGT(PtrVT)) {

394 IdxN =

396 }

397 return IdxN;

398}

399

405 } else

407}

408

411 assert(I.isValid() && E.isValid() && std::distance(I, E) > 0 &&

412 "Invalid iterator!");

413 while (I != E) {

414 if (SavedInsertPt == I)

415 SavedInsertPt = E;

420

422 ++I;

423 Dead->eraseFromParent();

424 ++NumFastIselDead;

425 }

427}

428

432 return OldInsertPt;

433}

434

438

439

441}

442

444 EVT VT = EVT::getEVT(I->getType(), true);

445 if (VT == MVT::Other || !VT.isSimple())

446

447 return false;

448

449

450

451

452

454

455

458 else

459 return false;

460 }

461

462

463

464 if (const auto *CI = dyn_cast(I->getOperand(0)))

465 if (isa(I) && cast(I)->isCommutative()) {

467 if (!Op1)

468 return false;

469

473 if (!ResultReg)

474 return false;

475

476

478 return true;

479 }

480

482 if (!Op0)

483 return false;

484

485

486 if (const auto *CI = dyn_cast(I->getOperand(1))) {

487 uint64_t Imm = CI->getSExtValue();

488

489

490 if (ISDOpcode == ISD::SDIV && isa(I) &&

491 cast(I)->isExact() && isPowerOf2_64(Imm)) {

494 }

495

496

497 if (ISDOpcode == ISD::UREM && isa(I) &&

499 --Imm;

501 }

502

505 if (!ResultReg)

506 return false;

507

508

510 return true;

511 }

512

514 if (!Op1)

515 return false;

516

517

519 ISDOpcode, Op0, Op1);

520 if (!ResultReg)

521

522

523 return false;

524

525

527 return true;

528}

529

532 if (N)

533 return false;

534

535

536

537 if (isa(I->getType()))

538 return false;

539

540

541

543

546

548 GTI != E; ++GTI) {

549 const Value *Idx = GTI.getOperand();

550 if (StructType *StTy = GTI.getStructTypeOrNull()) {

553

555 if (TotalOffs >= MaxOffs) {

557 if (N)

558 return false;

559 TotalOffs = 0;

560 }

561 }

562 } else {

563

564 if (const auto *CI = dyn_cast(Idx)) {

565 if (CI->isZero())

566 continue;

567

568 uint64_t IdxN = CI->getValue().sextOrTrunc(64).getSExtValue();

569 TotalOffs += GTI.getSequentialElementStride(DL) * IdxN;

570 if (TotalOffs >= MaxOffs) {

572 if (N)

573 return false;

574 TotalOffs = 0;

575 }

576 continue;

577 }

578 if (TotalOffs) {

580 if (N)

581 return false;

582 TotalOffs = 0;

583 }

584

585

586 uint64_t ElementSize = GTI.getSequentialElementStride(DL);

588 if (!IdxN)

589 return false;

590

591 if (ElementSize != 1) {

593 if (!IdxN)

594 return false;

595 }

597 if (N)

598 return false;

599 }

600 }

601 if (TotalOffs) {

603 if (N)

604 return false;

605 }

606

607

609 return true;

610}

611

613 const CallInst *CI, unsigned StartIdx) {

614 for (unsigned i = StartIdx, e = CI->arg_size(); i != e; ++i) {

616

617 if (const auto *C = dyn_cast(Val)) {

620 } else if (isa(Val)) {

623 } else if (auto *AI = dyn_cast(Val)) {

624

625

626

630 else

631 return false;

632 } else {

634 if (!Reg)

635 return false;

637 }

638 }

639 return true;

640}

641

643

644

645 assert(I->getCalledFunction()->getReturnType()->isVoidTy() &&

646 "Stackmap cannot return a value.");

647

648

649

650

651

652

653

654

655

656

657

659

660

662 "Expected a constant integer.");

665

667 "Expected a constant integer.");

668 const auto *NumBytes =

671

672

673

674 if (!addStackMapLiveVars(Ops, I, 2))

675 return false;

676

677

678

679

680

683 for (unsigned i = 0; ScratchRegs[i]; ++i)

685 ScratchRegs[i], true, true, false,

686 false, false, true));

687

688

690 auto Builder =

692 const MCInstrDesc &MCID = Builder.getInstr()->getDesc();

694 Builder.addImm(0);

695

696

698 TII.get(TargetOpcode::STACKMAP));

699 for (auto const &MO : Ops)

700 MIB.add(MO);

701

702

707

708

710

711 return true;

712}

713

714

715

716

717

718

719bool FastISel::lowerCallOperands(const CallInst *CI, unsigned ArgIdx,

720 unsigned NumArgs, const Value *Callee,

721 bool ForceRetVoidTy, CallLoweringInfo &CLI) {

723 Args.reserve(NumArgs);

724

725

726 for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs; ArgI != ArgE; ++ArgI) {

728

729 assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic.");

730

732 Entry.Val = V;

733 Entry.Ty = V->getType();

734 Entry.setAttributes(CI, ArgI);

735 Args.push_back(Entry);

736 }

737

740 CLI.setCallee(CI->getCallingConv(), RetTy, Callee, std::move(Args), NumArgs);

741

743}

744

751 return setCallee(CC, ResultTy, Sym, std::move(ArgsList), FixedArgs);

752}

753

755

756

757

758

759

760

763 bool HasDef = I->getType()->isVoidTy();

765

766

768 if (IsAnyRegCC && HasDef) {

771 return false;

772 }

773

774

776 "Expected a constant integer.");

777 const auto *NumArgsVal =

779 unsigned NumArgs = NumArgsVal->getZExtValue();

780

781

782

784 assert(I->arg_size() >= NumMetaOpers + NumArgs &&

785 "Not enough arguments provided to the patchpoint intrinsic");

786

787

788 unsigned NumCallArgs = IsAnyRegCC ? 0 : NumArgs;

791 if (!lowerCallOperands(I, NumMetaOpers, NumCallArgs, Callee, IsAnyRegCC, CLI))

792 return false;

793

794 assert(CLI.Call && "No call instruction specified.");

795

797

798

799 if (IsAnyRegCC && HasDef) {

805 }

806

807

809 "Expected a constant integer.");

812

814 "Expected a constant integer.");

815 const auto *NumBytes =

818

819

820 if (const auto *C = dyn_cast(Callee)) {

822 cast(C->getOperand(0))->getZExtValue();

824 } else if (const auto *C = dyn_cast(Callee)) {

825 if (C->getOpcode() == Instruction::IntToPtr) {

827 cast(C->getOperand(0))->getZExtValue();

829 } else

831 } else if (const auto *GV = dyn_cast(Callee)) {

833 } else if (isa(Callee))

835 else

837

838

839

840 unsigned NumCallRegArgs = IsAnyRegCC ? NumArgs : CLI.OutRegs.size();

842

843

845

846

847

848 if (IsAnyRegCC) {

849 for (unsigned i = NumMetaOpers, e = NumMetaOpers + NumArgs; i != e; ++i) {

851 if (!Reg)

852 return false;

854 }

855 }

856

857

858 for (auto Reg : CLI.OutRegs)

860

861

862 if (!addStackMapLiveVars(Ops, I, NumMetaOpers + NumArgs))

863 return false;

864

865

868

869

871 for (unsigned i = 0; ScratchRegs[i]; ++i)

873 ScratchRegs[i], true, true, false,

874 false, false, true));

875

876

877 for (auto Reg : CLI.InRegs)

879 true));

880

881

883 TII.get(TargetOpcode::PATCHPOINT));

884

885 for (auto &MO : Ops)

886 MIB.add(MO);

887

889

890

892

893

895

898 return true;

899}

900

904 return true;

907 false));

909 false));

912 TII.get(TargetOpcode::PATCHABLE_EVENT_CALL));

913 for (auto &MO : Ops)

914 MIB.add(MO);

915

916

917 return true;

918}

919

923 return true;

926 false));

928 false));

930 false));

933 TII.get(TargetOpcode::PATCHABLE_TYPED_EVENT_CALL));

934 for (auto &MO : Ops)

935 MIB.add(MO);

936

937

938 return true;

939}

940

941

942

946 Attrs.push_back(Attribute::SExt);

948 Attrs.push_back(Attribute::ZExt);

950 Attrs.push_back(Attribute::InReg);

951

953 Attrs);

954}

955

957 unsigned NumArgs) {

963}

964

966 unsigned NumArgs) {

969

971 Args.reserve(NumArgs);

972

973

974

975 for (unsigned ArgI = 0; ArgI != NumArgs; ++ArgI) {

977

978 assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic.");

979

981 Entry.Val = V;

982 Entry.Ty = V->getType();

983 Entry.setAttributes(CI, ArgI);

984 Args.push_back(Entry);

985 }

987

989 CLI.setCallee(RetTy, FTy, Symbol, std::move(Args), *CI, NumArgs);

990

992}

993

995

999

1002

1005

1006

1007 if (!CanLowerReturn)

1008 return false;

1009

1010 for (EVT VT : RetTys) {

1013 for (unsigned i = 0; i != NumRegs; ++i) {

1015 MyFlags.VT = RegisterVT;

1016 MyFlags.ArgVT = VT;

1024 CLI.Ins.push_back(MyFlags);

1025 }

1026 }

1027

1028

1030 for (auto &Arg : CLI.getArgs()) {

1031 Type *FinalType = Arg.Ty;

1032 if (Arg.IsByVal)

1033 FinalType = Arg.IndirectType;

1036

1038 if (Arg.IsZExt)

1039 Flags.setZExt();

1040 if (Arg.IsSExt)

1041 Flags.setSExt();

1042 if (Arg.IsInReg)

1043 Flags.setInReg();

1044 if (Arg.IsSRet)

1045 Flags.setSRet();

1046 if (Arg.IsSwiftSelf)

1047 Flags.setSwiftSelf();

1048 if (Arg.IsSwiftAsync)

1049 Flags.setSwiftAsync();

1050 if (Arg.IsSwiftError)

1051 Flags.setSwiftError();

1052 if (Arg.IsCFGuardTarget)

1053 Flags.setCFGuardTarget();

1054 if (Arg.IsByVal)

1055 Flags.setByVal();

1056 if (Arg.IsInAlloca) {

1057 Flags.setInAlloca();

1058

1059

1060

1061

1062

1063 Flags.setByVal();

1064 }

1065 if (Arg.IsPreallocated) {

1066 Flags.setPreallocated();

1067

1068

1069

1070

1071

1072 Flags.setByVal();

1073 }

1074 MaybeAlign MemAlign = Arg.Alignment;

1075 if (Arg.IsByVal || Arg.IsInAlloca || Arg.IsPreallocated) {

1077

1078

1079

1080 if (!MemAlign)

1082 Flags.setByValSize(FrameSize);

1083 } else if (!MemAlign) {

1085 }

1086 Flags.setMemAlign(*MemAlign);

1087 if (Arg.IsNest)

1088 Flags.setNest();

1089 if (NeedsRegBlock)

1090 Flags.setInConsecutiveRegs();

1092 CLI.OutVals.push_back(Arg.Val);

1093 CLI.OutFlags.push_back(Flags);

1094 }

1095

1097 return false;

1098

1099

1100 assert(CLI.Call && "No call instruction specified.");

1102

1105

1106

1107 if (CLI.CB)

1110

1111 return true;

1112}

1113

1117

1120 Args.reserve(CI->arg_size());

1121

1122 for (auto i = CI->arg_begin(), e = CI->arg_end(); i != e; ++i) {

1124

1125

1126 if (V->getType()->isEmptyTy())

1127 continue;

1128

1129 Entry.Val = V;

1130 Entry.Ty = V->getType();

1131

1132

1133 Entry.setAttributes(CI, i - CI->arg_begin());

1134 Args.push_back(Entry);

1135 }

1136

1137

1138

1141 IsTailCall = false;

1144 IsTailCall = false;

1145

1149

1151

1153}

1154

1156 const CallInst *Call = cast(I);

1157

1158

1159 if (const InlineAsm *IA = dyn_cast(Call->getCalledOperand())) {

1160

1161 if (!IA->getConstraintString().empty())

1162 return false;

1163

1164 unsigned ExtraInfo = 0;

1165 if (IA->hasSideEffects())

1167 if (IA->isAlignStack())

1169 if (Call->isConvergent())

1172

1174 TII.get(TargetOpcode::INLINEASM));

1176 MIB.addImm(ExtraInfo);

1177

1178 const MDNode *SrcLoc = Call->getMetadata("srcloc");

1179 if (SrcLoc)

1181

1182 return true;

1183 }

1184

1185

1186 if (const auto *II = dyn_cast(Call))

1188

1190}

1191

1193 if (II->hasDbgRecords())

1194 return;

1195

1196

1198

1199

1201 flushLocalValueMap();

1203

1204 if (DbgLabelRecord *DLR = dyn_cast(&DR)) {

1205 assert(DLR->getLabel() && "Missing label");

1207 TII.get(TargetOpcode::DBG_LABEL))

1209 continue;

1210 }

1211

1213

1214 Value *V = nullptr;

1217

1218 bool Res = false;

1223 } else {

1226 continue;

1229 }

1230

1231 if (!Res)

1232 LLVM_DEBUG(dbgs() << "Dropping debug-info for " << DVR << "\n");

1233 }

1234}

1235

1238

1240 if (!V || isa(V)) {

1241

1242

1244 return true;

1245 }

1246 if (const auto *CI = dyn_cast(V)) {

1247

1248 if (Expr)

1249 std::tie(Expr, CI) = Expr->constantFold(CI);

1250 if (CI->getBitWidth() > 64)

1256 else

1258 .addImm(CI->getZExtValue())

1262 return true;

1263 }

1264 if (const auto *CF = dyn_cast(V)) {

1270 return true;

1271 }

1272 if (const auto *Arg = dyn_cast(V);

1274

1275 assert(Arg->hasAttribute(Attribute::AttrKind::SwiftAsync));

1276

1279 if (Reg == VirtReg || Reg == PhysReg) {

1281 PhysReg, Var, Expr);

1282 return true;

1283 }

1284

1285 LLVM_DEBUG(dbgs() << "Dropping dbg.value: expression is entry_value but "

1286 "couldn't find a physical register\n");

1287 return false;

1288 }

1292 bool IsIndirect = false;

1294 Var, Expr);

1295 return true;

1296 }

1298

1300 bool IsIndirect = false;

1302 Expr);

1303 return true;

1304 }

1305

1306

1308 Reg, false, false,

1309 false, false,

1310 false, false,

1311 0, true)});

1315 TII.get(TargetOpcode::DBG_INSTR_REF), false, MOs,

1317 return true;

1318 }

1319 return false;

1320}

1321

1325 LLVM_DEBUG(dbgs() << "Dropping debug info (bad/undef address)\n");

1326 return false;

1327 }

1328

1329 std::optional Op;

1332

1333

1334

1335

1336

1337

1338

1339

1340

1341

1342

1343

1344 if (Op && Address->use_empty() && isa(Address) &&

1345 (!isa(Address) ||

1348 false);

1349

1350 if (Op) {

1352 "Expected inlined-at fields to agree");

1354

1355

1356

1361 TII.get(TargetOpcode::DBG_INSTR_REF), false, *Op,

1363 return true;

1364 }

1365

1366

1367

1369 TII.get(TargetOpcode::DBG_VALUE), true, *Op, Var,

1370 Expr);

1371 return true;

1372 }

1373

1374

1375

1377 dbgs() << "Dropping debug info (no materialized reg for address)\n");

1378 return false;

1379}

1380

1382 switch (II->getIntrinsicID()) {

1383 default:

1384 break;

1385

1386 case Intrinsic::lifetime_start:

1387 case Intrinsic::lifetime_end:

1388

1389 case Intrinsic::donothing:

1390

1391 case Intrinsic::sideeffect:

1392

1393 case Intrinsic::assume:

1394

1395 case Intrinsic::experimental_noalias_scope_decl:

1396 return true;

1397 case Intrinsic::dbg_declare: {

1401 return true;

1402

1406 LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI);

1407

1408 return true;

1409 }

1410 case Intrinsic::dbg_assign:

1411

1412

1413

1414

1415

1416 [[fallthrough]];

1417 case Intrinsic::dbg_value: {

1418

1424

1425 V = nullptr;

1426

1428 "Expected inlined-at fields to agree");

1429

1431 LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");

1432

1433 return true;

1434 }

1435 case Intrinsic::dbg_label: {

1440 return true;

1441 }

1442 case Intrinsic::objectsize:

1443 llvm_unreachable("llvm.objectsize.* should have been lowered already");

1444

1445 case Intrinsic::is_constant:

1446 llvm_unreachable("llvm.is.constant.* should have been lowered already");

1447

1448 case Intrinsic::allow_runtime_check:

1449 case Intrinsic::allow_ubsan_check: {

1451 if (!ResultReg)

1452 return false;

1454 return true;

1455 }

1456

1457 case Intrinsic::launder_invariant_group:

1458 case Intrinsic::strip_invariant_group:

1459 case Intrinsic::expect:

1460 case Intrinsic::expect_with_probability: {

1462 if (!ResultReg)

1463 return false;

1465 return true;

1466 }

1467 case Intrinsic::fake_use:

1468

1469 return true;

1470 case Intrinsic::experimental_stackmap:

1472 case Intrinsic::experimental_patchpoint_void:

1473 case Intrinsic::experimental_patchpoint:

1475

1476 case Intrinsic::xray_customevent:

1478 case Intrinsic::xray_typedevent:

1480 }

1481

1483}

1484

1488

1489 if (SrcVT == MVT::Other || !SrcVT.isSimple() || DstVT == MVT::Other ||

1491

1492 return false;

1493

1494

1496 return false;

1497

1498

1500 return false;

1501

1503 if (!InputReg)

1504

1505 return false;

1506

1508 Opcode, InputReg);

1509 if (!ResultReg)

1510 return false;

1511

1513 return true;

1514}

1515

1519 if (SrcEVT == MVT::Other || DstEVT == MVT::Other ||

1521

1522 return false;

1523

1527 if (!Op0)

1528 return false;

1529

1530

1531 if (SrcVT == DstVT) {

1533 return true;

1534 }

1535

1536

1538 if (!ResultReg)

1539 return false;

1540

1542 return true;

1543}

1544

1547 if (!Reg)

1548

1549 return false;

1550

1553

1554 return false;

1555

1560 TII.get(TargetOpcode::COPY), ResultReg).addReg(Reg);

1561

1563 return true;

1564}

1565

1566

1567

1568void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue)

1569{

1571 if (CurLastLocalValue != SavedLastLocalValue) {

1572

1573

1574

1576 if (SavedLastLocalValue)

1577 ++FirstDeadInst;

1578 else

1582 }

1583}

1584

1586

1587

1588

1589 flushLocalValueMap();

1590

1592

1593

1594 if (I->isTerminator()) {

1595 if (!handlePHINodesInSuccessorBlocks(I->getParent())) {

1596

1597

1598

1599

1600 removeDeadLocalValueCode(SavedLastLocalValue);

1601 return false;

1602 }

1603 }

1604

1605

1606 if (auto *Call = dyn_cast(I))

1607 for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i)

1609 return false;

1610

1612

1614

1615 if (const auto *Call = dyn_cast(I)) {

1616 const Function *F = Call->getCalledFunction();

1618

1619

1620

1621 if (F && F->hasLocalLinkage() && F->hasName() &&

1624 return false;

1625

1626

1627 if (F && F->getIntrinsicID() == Intrinsic::trap &&

1628 Call->hasFnAttr("trap-func-name"))

1629 return false;

1630 }

1631

1632

1635 ++NumFastIselSuccessIndependent;

1637 return true;

1638 }

1639

1644 }

1645

1647 ++NumFastIselSuccessTarget;

1649 return true;

1650 }

1651

1655

1657

1658 if (I->isTerminator()) {

1659

1660

1661 removeDeadLocalValueCode(SavedLastLocalValue);

1663 }

1664 return false;

1665}

1666

1667

1668

1672 bool BlockHasMultipleInstrs = &BB->front() != &BB->back();

1673

1677

1678

1679

1680 } else {

1681

1684 }

1689 } else

1691}

1692

1696

1697

1698

1699 if (TrueMBB != FalseMBB) {

1704 } else

1706 }

1707

1709}

1710

1711

1714 if (!OpReg)

1715 return false;

1716

1717

1720 OpReg);

1721 if (ResultReg) {

1723 return true;

1724 }

1725

1726

1727

1729 return false;

1732 return false;

1733

1736 if (!IntReg)

1737 return false;

1738

1742 if (!IntResultReg)

1743 return false;

1744

1746 IntResultReg);

1747 if (!ResultReg)

1748 return false;

1749

1751 return true;

1752}

1753

1755 const ExtractValueInst *EVI = dyn_cast(U);

1756 if (!EVI)

1757 return false;

1758

1759

1760

1763 return false;

1766 return false;

1767

1770

1771

1772 unsigned ResultReg;

1775 ResultReg = I->second;

1776 else if (isa(Op0))

1778 else

1779 return false;

1780

1781

1783

1786

1787 for (unsigned i = 0; i < VTIndex; i++)

1789

1791 return true;

1792}

1793

1795 switch (Opcode) {

1796 case Instruction::Add:

1798 case Instruction::FAdd:

1800 case Instruction::Sub:

1802 case Instruction::FSub:

1804 case Instruction::Mul:

1806 case Instruction::FMul:

1808 case Instruction::SDiv:

1810 case Instruction::UDiv:

1812 case Instruction::FDiv:

1814 case Instruction::SRem:

1816 case Instruction::URem:

1818 case Instruction::FRem:

1820 case Instruction::Shl:

1822 case Instruction::LShr:

1824 case Instruction::AShr:

1826 case Instruction::And:

1828 case Instruction::Or:

1830 case Instruction::Xor:

1832

1833 case Instruction::FNeg:

1835

1836 case Instruction::GetElementPtr:

1838

1839 case Instruction::Br: {

1840 const BranchInst *BI = cast(I);

1841

1846 return true;

1847 }

1848

1849

1850

1851 return false;

1852 }

1853

1854 case Instruction::Unreachable: {

1857 const auto *Call =

1858 dyn_cast_or_null(cast(I)->getPrevNode());

1859 if (Call && Call->doesNotReturn())

1860 return true;

1861 }

1862

1864 }

1865 return true;

1866 }

1867

1868 case Instruction::Alloca:

1869

1871 return true;

1872

1873

1874 return false;

1875

1876 case Instruction::Call:

1877

1878

1879

1880

1881

1882

1884 return false;

1886

1887 case Instruction::BitCast:

1889

1890 case Instruction::FPToSI:

1892 case Instruction::ZExt:

1894 case Instruction::SExt:

1896 case Instruction::Trunc:

1898 case Instruction::SIToFP:

1900

1901 case Instruction::IntToPtr:

1902 case Instruction::PtrToInt: {

1905 if (DstVT.bitsGT(SrcVT))

1907 if (DstVT.bitsLT(SrcVT))

1910 if (!Reg)

1911 return false;

1913 return true;

1914 }

1915

1916 case Instruction::ExtractValue:

1918

1919 case Instruction::Freeze:

1921

1922 case Instruction::PHI:

1924

1925 default:

1926

1927 return false;

1928 }

1929}

1930

1937 TII(*MF->getSubtarget().getInstrInfo()),

1938 TLI(*MF->getSubtarget().getTargetLowering()),

1941

1943

1945

1947

1949 return false;

1950}

1951

1953

1955 return 0;

1956}

1957

1959 unsigned ) {

1960 return 0;

1961}

1962

1964 return 0;

1965}

1966

1969 return 0;

1970}

1971

1974 return 0;

1975}

1976

1977

1978

1979

1980

1983

1988

1991 }

1992

1993

1994

1997 return 0;

1998

1999

2001 if (ResultReg)

2002 return ResultReg;

2004 if (!MaterialReg) {

2005

2006

2009 MaterialReg = getRegForValue(ConstantInt::get(ITy, Imm));

2010 if (!MaterialReg)

2011 return 0;

2012 }

2013 return fastEmit_rr(VT, VT, Opcode, Op0, MaterialReg);

2014}

2015

2018}

2019

2021 unsigned OpNum) {

2022 if (Op.isVirtual()) {

2026

2027

2031 return NewOp;

2032 }

2033 }

2034 return Op;

2035}

2036

2041

2043 return ResultReg;

2044}

2045

2049

2052

2053 if (II.getNumDefs() >= 1)

2056 else {

2060 ResultReg)

2061 .addReg(II.implicit_defs()[0]);

2062 }

2063

2064 return ResultReg;

2065}

2066

2069 unsigned Op1) {

2071

2075

2076 if (II.getNumDefs() >= 1)

2080 else {

2085 ResultReg)

2086 .addReg(II.implicit_defs()[0]);

2087 }

2088 return ResultReg;

2089}

2090

2093 unsigned Op1, unsigned Op2) {

2095

2100

2101 if (II.getNumDefs() >= 1)

2106 else {

2112 ResultReg)

2113 .addReg(II.implicit_defs()[0]);

2114 }

2115 return ResultReg;

2116}

2117

2122

2125

2126 if (II.getNumDefs() >= 1)

2130 else {

2135 ResultReg)

2136 .addReg(II.implicit_defs()[0]);

2137 }

2138 return ResultReg;

2139}

2140

2145

2148

2149 if (II.getNumDefs() >= 1)

2154 else {

2160 ResultReg)

2161 .addReg(II.implicit_defs()[0]);

2162 }

2163 return ResultReg;

2164}

2165

2170

2172

2173 if (II.getNumDefs() >= 1)

2176 else {

2180 ResultReg)

2181 .addReg(II.implicit_defs()[0]);

2182 }

2183 return ResultReg;

2184}

2185

2188 unsigned Op1, uint64_t Imm) {

2190

2194

2195 if (II.getNumDefs() >= 1)

2200 else {

2206 ResultReg)

2207 .addReg(II.implicit_defs()[0]);

2208 }

2209 return ResultReg;

2210}

2211

2216

2217 if (II.getNumDefs() >= 1)

2220 else {

2223 ResultReg)

2224 .addReg(II.implicit_defs()[0]);

2225 }

2226 return ResultReg;

2227}

2228

2233 "Cannot yet extract from physregs");

2238 return ResultReg;

2239}

2240

2241

2242

2245}

2246

2247

2248

2249

2250

2251

2252

2253bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {

2256

2257

2258

2260 if (!isa(SuccBB->begin()))

2261 continue;

2263

2264

2265

2266 if (!SuccsHandled.insert(SuccMBB).second)

2267 continue;

2268

2270

2271

2272

2273

2274 for (const PHINode &PN : SuccBB->phis()) {

2275

2276 if (PN.use_empty())

2277 continue;

2278

2279

2280

2281

2282

2283

2284

2287

2288 if (!(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)) {

2290 return false;

2291 }

2292 }

2293

2294 const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB);

2295

2296

2297

2299 if (const auto *Inst = dyn_cast(PHIOp))

2301

2303 if (!Reg) {

2305 return false;

2306 }

2309 }

2310 }

2311

2312 return true;

2313}

2314

2317 "tryToFoldLoad expected a LoadInst with a single use");

2318

2319

2320

2321 unsigned MaxUsers = 6;

2322

2324 while (TheUser != FoldInst &&

2325

2327 --MaxUsers) {

2328

2330 return false;

2331

2333 }

2334

2335

2336

2337 if (TheUser != FoldInst)

2338 return false;

2339

2340

2341

2343 return false;

2344

2345

2346

2347

2349 if (!LoadReg)

2350 return false;

2351

2352

2353

2354

2356 return false;

2357

2358

2359

2361 return false;

2362

2365

2366

2367

2368

2371

2372

2374}

2375

2377

2378 if (!isa(Add))

2379 return false;

2380

2383 return false;

2384

2385 if (isa(Add) &&

2387 return false;

2388

2389 return isa(cast(Add)->getOperand(1));

2390}

2391

2395 Type *ValTy;

2398 bool IsVolatile;

2399

2400 if (const auto *LI = dyn_cast(I)) {

2401 Alignment = LI->getAlign();

2402 IsVolatile = LI->isVolatile();

2404 Ptr = LI->getPointerOperand();

2405 ValTy = LI->getType();

2406 } else if (const auto *SI = dyn_cast(I)) {

2407 Alignment = SI->getAlign();

2408 IsVolatile = SI->isVolatile();

2410 Ptr = SI->getPointerOperand();

2411 ValTy = SI->getValueOperand()->getType();

2412 } else

2413 return nullptr;

2414

2415 bool IsNonTemporal = I->hasMetadata(LLVMContext::MD_nontemporal);

2416 bool IsInvariant = I->hasMetadata(LLVMContext::MD_invariant_load);

2417 bool IsDereferenceable = I->hasMetadata(LLVMContext::MD_dereferenceable);

2418 const MDNode *Ranges = I->getMetadata(LLVMContext::MD_range);

2419

2420 AAMDNodes AAInfo = I->getAAMetadata();

2421

2422 if (!Alignment)

2424

2426

2427 if (IsVolatile)

2429 if (IsNonTemporal)

2431 if (IsDereferenceable)

2433 if (IsInvariant)

2435

2437 *Alignment, AAInfo, Ranges);

2438}

2439

2441

2444 return Predicate;

2445

2446 switch (Predicate) {

2464

2475 }

2476

2477 return Predicate;

2478}

This file declares a class to represent arbitrary precision floating point values and provide a varie...

This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

This file contains the simple types necessary to represent the attributes associated with functions a...

This file contains the declarations for the subclasses of Constant, which represent the different fla...

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 defines the DenseMap class.

static Register findLocalRegDef(MachineInstr &MI)

Return the defined register if this instruction defines exactly one virtual register and uses no othe...

static bool isRegUsedByPhiNodes(Register DefReg, FunctionLoweringInfo &FuncInfo)

static AttributeList getReturnAttrs(FastISel::CallLoweringInfo &CLI)

Returns an AttributeList representing the attributes applied to the return value of the given call.

This file defines the FastISel class.

Module.h This file contains the declarations for the Module class.

uint64_t IntrinsicInst * II

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

static bool isCommutative(Instruction *I)

This file defines the SmallPtrSet class.

This file defines the SmallString class.

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static SymbolRef::Type getType(const Symbol *Sym)

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

An arbitrary precision integer that knows its signedness.

This class represents an incoming formal argument to a Function.

static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)

Create an AttributeList with the specified parameters in it.

bool getValueAsBool() const

Return the attribute's value as a boolean.

LLVM Basic Block Representation.

const Instruction & front() const

filter_iterator< BasicBlock::const_iterator, std::function< bool(constInstruction &)> >::difference_type sizeWithoutDebug() const

Return the size of the basic block ignoring debug instructions.

const Instruction & back() const

const Module * getModule() const

Return the module owning the function this basic block belongs to, or nullptr if the function does no...

Conditional or Unconditional Branch instruction.

BasicBlock * getSuccessor(unsigned i) const

bool isUnconditional() const

BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const

Get an edge's probability, relative to other out-edges of the Src.

CallingConv::ID getCallingConv() const

User::op_iterator arg_begin()

Return the iterator pointing to the beginning of the argument list.

Value * getCalledOperand() const

Value * getArgOperand(unsigned i) const

User::op_iterator arg_end()

Return the iterator pointing to the end of the argument list.

FunctionType * getFunctionType() const

unsigned arg_size() const

This class represents a function call, abstracting a target machine's calling convention.

bool isMustTailCall() const

This class is the base class for the comparison instructions.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ FCMP_TRUE

1 1 1 1 Always true (always folded)

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_ULE

1 1 0 1 True if unordered, less than, or equal

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_OGE

0 0 1 1 True if ordered and greater than or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ FCMP_ULT

1 1 0 0 True if unordered or less than

@ FCMP_ONE

0 1 1 0 True if ordered and operands are unequal

@ FCMP_UEQ

1 0 0 1 True if unordered or equal

@ ICMP_ULT

unsigned less than

@ FCMP_UGT

1 0 1 0 True if unordered or greater than

@ FCMP_OLE

0 1 0 1 True if ordered and less than or equal

@ FCMP_ORD

0 1 1 1 True if ordered (no nans)

@ ICMP_SGE

signed greater or equal

@ FCMP_UNE

1 1 1 0 True if unordered or not equal

@ ICMP_ULE

unsigned less or equal

@ FCMP_UGE

1 0 1 1 True if unordered, greater than, or equal

@ FCMP_FALSE

0 0 0 0 Always false (always folded)

@ FCMP_UNO

1 0 0 0 True if unordered: isnan(X) | isnan(Y)

Predicate getPredicate() const

Return the predicate for this instruction.

ConstantFP - Floating Point Values [float, double].

static ConstantInt * getTrue(LLVMContext &Context)

static Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

bool isEntryValue() const

Check if the expression consists of exactly one entry value operand.

std::pair< DIExpression *, const ConstantInt * > constantFold(const ConstantInt *CI)

Try to shorten an expression with an initial constant operand.

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.

bool isValidLocationForIntrinsic(const DILocation *DL) const

Check that a location is valid for this variable.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

const StructLayout * getStructLayout(StructType *Ty) const

Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...

IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const

Returns an integer type with size at least as big as that of a pointer in the given address space.

Align getABITypeAlign(Type *Ty) const

Returns the minimum ABI-required alignment for the specified type.

TypeSize getTypeAllocSize(Type *Ty) const

Returns the offset in bytes between successive objects of the specified type, including alignment pad...

TypeSize getTypeSizeInBits(Type *Ty) const

Size examples:

TypeSize getTypeStoreSize(Type *Ty) const

Returns the maximum number of bytes that may be overwritten by storing the specified type.

This represents the llvm.dbg.declare instruction.

Value * getAddress() const

This represents the llvm.dbg.label instruction.

DILabel * getLabel() const

Records a position in IR for a source label (DILabel).

Base class for non-instruction debug metadata records that have positions within IR.

DebugLoc getDebugLoc() const

This represents the llvm.dbg.value instruction.

Value * getValue(unsigned OpIdx=0) const

DILocalVariable * getVariable() const

DIExpression * getExpression() const

Record of a variable value-assignment, aka a non instruction representation of the dbg....

LocationType getType() const

DIExpression * getExpression() const

Value * getVariableLocationOp(unsigned OpIdx) const

DILocalVariable * getVariable() const

MachineRegisterInfo & MRI

Register fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, uint32_t Idx)

Emit a MachineInstr for an extract_subreg from a specified index of a superregister to a specified ty...

const TargetLibraryInfo * LibInfo

bool selectGetElementPtr(const User *I)

void setLastLocalValue(MachineInstr *I)

Update the position of the last instruction emitted for materializing constants for use in the curren...

bool selectStackmap(const CallInst *I)

bool selectExtractValue(const User *U)

DenseMap< const Value *, Register > LocalValueMap

void fastEmitBranch(MachineBasicBlock *MSucc, const DebugLoc &DbgLoc)

Emit an unconditional branch to the given block, unless it is the immediate (fall-through) successor,...

virtual unsigned fastMaterializeFloatZero(const ConstantFP *CF)

Emit the floating-point constant +0.0 in a register using target- specific logic.

MachineInstr * EmitStartPt

The top most instruction in the current block that is allowed for emitting local variables.

bool selectXRayCustomEvent(const CallInst *II)

Register fastEmitInst_(unsigned MachineInstOpcode, const TargetRegisterClass *RC)

Emit a MachineInstr with no operands and a result register in the given register class.

virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II)

This method is called by target-independent code to do target- specific intrinsic lowering.

virtual bool lowerDbgDeclare(const Value *V, DIExpression *Expr, DILocalVariable *Var, const DebugLoc &DL)

Target-independent lowering of debug information.

MachineInstr * getLastLocalValue()

Return the position of the last instruction emitted for materializing constants for use in the curren...

bool lowerCall(const CallInst *I)

virtual unsigned fastEmit_ri(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0, uint64_t Imm)

This method is called by target-independent code to request that an instruction with the given type,...

void leaveLocalValueArea(SavePoint Old)

Reset InsertPt to the given old insert position.

bool lowerCallTo(const CallInst *CI, MCSymbol *Symbol, unsigned NumArgs)

Register fastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0)

Emit a MachineInstr with one register operand and a result register in the given register class.

void handleDbgInfo(const Instruction *II)

Target-independent lowering of non-instruction debug info associated with this instruction.

bool selectFreeze(const User *I)

bool selectIntrinsicCall(const IntrinsicInst *II)

Register getRegForGEPIndex(MVT PtrVT, const Value *Idx)

This is a wrapper around getRegForValue that also takes care of truncating or sign-extending the give...

bool selectCast(const User *I, unsigned Opcode)

bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst)

We're checking to see if we can fold LI into FoldInst.

Register getRegForValue(const Value *V)

Create a virtual register and arrange for it to be assigned the value for the given LLVM value.

void removeDeadCode(MachineBasicBlock::iterator I, MachineBasicBlock::iterator E)

Remove all dead instructions between the I and E.

void startNewBlock()

Set the current block to which generated machine instructions will be appended.

MachineMemOperand * createMachineMemOperandFor(const Instruction *I) const

Create a machine mem operand from the given instruction.

virtual bool tryToFoldLoadIntoMI(MachineInstr *, unsigned, const LoadInst *)

The specified machine instr operand is a vreg, and that vreg is being provided by the specified load ...

Register fastEmitInst_i(unsigned MachineInstOpcode, const TargetRegisterClass *RC, uint64_t Imm)

Emit a MachineInstr with a single immediate operand, and a result register in the given register clas...

bool canFoldAddIntoGEP(const User *GEP, const Value *Add)

Check if Add is an add that can be safely folded into GEP.

virtual bool lowerDbgValue(const Value *V, DIExpression *Expr, DILocalVariable *Var, const DebugLoc &DL)

Target-independent lowering of debug information.

virtual unsigned fastEmit_(MVT VT, MVT RetVT, unsigned Opcode)

This method is called by target-independent code to request that an instruction with the given type a...

TargetLoweringBase::ArgListTy ArgListTy

bool selectInstruction(const Instruction *I)

Do "fast" instruction selection for the given LLVM IR instruction and append the generated machine in...

virtual unsigned fastMaterializeConstant(const Constant *C)

Emit a constant in a register using target-specific logic, such as constant pool loads.

virtual bool fastLowerCall(CallLoweringInfo &CLI)

This method is called by target-independent code to do target- specific call lowering.

bool selectXRayTypedEvent(const CallInst *II)

Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, unsigned Op1)

Emit a MachineInstr with two register operands and a result register in the given register class.

Register fastEmitInst_rii(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, uint64_t Imm1, uint64_t Imm2)

Emit a MachineInstr with one register operand and two immediate operands.

Register createResultReg(const TargetRegisterClass *RC)

virtual unsigned fastEmit_f(MVT VT, MVT RetVT, unsigned Opcode, const ConstantFP *FPImm)

This method is called by target-independent code to request that an instruction with the given type,...

virtual bool fastLowerArguments()

This method is called by target-independent code to do target- specific argument lowering.

bool selectFNeg(const User *I, const Value *In)

Emit an FNeg operation.

const TargetInstrInfo & TII

bool selectCall(const User *I)

Register lookUpRegForValue(const Value *V)

Look up the value to see if its value is already cached in a register.

CmpInst::Predicate optimizeCmpPredicate(const CmpInst *CI) const

void finishBasicBlock()

Flush the local value map.

FunctionLoweringInfo & FuncInfo

MachineConstantPool & MCP

bool selectOperator(const User *I, unsigned Opcode)

Do "fast" instruction selection for the given LLVM IR operator (Instruction or ConstantExpr),...

bool SkipTargetIndependentISel

Register fastEmitInst_f(unsigned MachineInstOpcode, const TargetRegisterClass *RC, const ConstantFP *FPImm)

Emit a MachineInstr with a floating point immediate, and a result register in the given register clas...

Register constrainOperandRegClass(const MCInstrDesc &II, Register Op, unsigned OpNum)

Try to constrain Op so that it is usable by argument OpNum of the provided MCInstrDesc.

void updateValueMap(const Value *I, Register Reg, unsigned NumRegs=1)

Update the value map to include the new mapping for this instruction, or insert an extra copy to get ...

bool selectBinaryOp(const User *I, unsigned ISDOpcode)

Select and emit code for a binary operator instruction, which has an opcode which directly correspond...

FastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, bool SkipTargetIndependentISel=false)

bool selectPatchpoint(const CallInst *I)

void recomputeInsertPt()

Reset InsertPt to prepare for inserting instructions into the current block.

virtual bool fastSelectInstruction(const Instruction *I)=0

This method is called by target-independent code when the normal FastISel process fails to select an ...

const TargetLowering & TLI

virtual unsigned fastEmit_rr(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0, unsigned Op1)

This method is called by target-independent code to request that an instruction with the given type,...

Register fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, uint64_t Imm, MVT ImmType)

This method is a wrapper of fastEmit_ri.

Register fastEmitZExtFromI1(MVT VT, unsigned Op0)

Emit MachineInstrs to compute the value of Op with all but the least significant bit set to zero.

MachineInstr * LastLocalValue

The position of the last instruction for materializing constants for use in the current block.

Register fastEmitInst_rri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, unsigned Op1, uint64_t Imm)

Emit a MachineInstr with two register operands, an immediate, and a result register in the given regi...

bool lowerArguments()

Do "fast" instruction selection for function arguments and append the machine instructions to the cur...

SavePoint enterLocalValueArea()

Prepare InsertPt to begin inserting instructions into the local value area and return the old insert ...

void finishCondBranch(const BasicBlock *BranchBB, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB)

Emit an unconditional branch to FalseMBB, obtains the branch weight and adds TrueMBB and FalseMBB to ...

bool selectBitCast(const User *I)

Register fastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, uint64_t Imm)

Emit a MachineInstr with a register operand, an immediate, and a result register in the given registe...

virtual unsigned fastEmit_r(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0)

This method is called by target-independent code to request that an instruction with the given type,...

virtual unsigned fastMaterializeAlloca(const AllocaInst *C)

Emit an alloca address in a register using target-specific logic.

virtual unsigned fastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm)

This method is called by target-independent code to request that an instruction with the given type,...

const TargetRegisterInfo & TRI

Register fastEmitInst_rrr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, unsigned Op1, unsigned Op2)

Emit a MachineInstr with three register operands and a result register in the given register class.

TargetLoweringBase::ArgListEntry ArgListEntry

FunctionLoweringInfo - This contains information that is global to a function that is used when lower...

BranchProbabilityInfo * BPI

SmallPtrSet< const DbgVariableRecord *, 8 > PreprocessedDVRDeclares

MachineBasicBlock * getMBB(const BasicBlock *BB) const

DenseSet< Register > RegsWithFixups

unsigned OrigNumPHINodesToUpdate

DenseMap< const AllocaInst *, int > StaticAllocaMap

StaticAllocaMap - Keep track of frame indices for fixed sized allocas in the entry block.

Register InitializeRegForValue(const Value *V)

SmallPtrSet< const DbgDeclareInst *, 8 > PreprocessedDbgDeclares

Collection of dbg.declare instructions handled after argument lowering and before ISel proper.

DenseMap< const Value *, Register > ValueMap

ValueMap - Since we emit code for the function a basic block at a time, we must remember which virtua...

MachineBasicBlock::iterator InsertPt

MBB - The current insert position inside the current block.

MachineBasicBlock * MBB

MBB - The current block.

std::vector< std::pair< MachineInstr *, unsigned > > PHINodesToUpdate

PHINodesToUpdate - A list of phi instructions whose operand list will be updated after processing the...

DenseMap< Register, Register > RegFixups

RegFixups - Registers which need to be replaced after isel is done.

MachineRegisterInfo * RegInfo

bool CanLowerReturn

CanLowerReturn - true iff the function's return value can be lowered to registers.

Class to represent function types.

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.

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

Instruction * user_back()

Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...

MDNode * getMetadata(unsigned KindID) const

Get the metadata of given kind attached to this Instruction.

Class to represent integer types.

static IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

A wrapper class for inspecting calls to intrinsic functions.

An instruction for reading from memory.

bool isVolatile() const

Return true if this is a load from a volatile memory location.

Context object for machine code objects.

MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

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

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

const MCInstrDesc & get(unsigned Opcode) const

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

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

TypeSize getSizeInBits() const

Returns the size of the specified MVT in bits.

void addSuccessorWithoutProb(MachineBasicBlock *Succ)

Add Succ as a successor of this MachineBasicBlock.

const BasicBlock * getBasicBlock() const

Return the LLVM basic block that this instance corresponded to originally.

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

Add Succ as a successor of this MachineBasicBlock.

iterator getFirstNonPHI()

Returns a pointer to the first instruction in this block that is not a PHINode instruction.

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

bool isLayoutSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...

MachineInstrBundleIterator< MachineInstr > iterator

void setHasPatchPoint(bool s=true)

void setHasStackMap(bool s=true)

bool useDebugInstrRef() const

Returns true if the function's variable locations are tracked with instruction referencing.

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.

MCContext & getContext() const

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const

const MachineInstrBuilder & addCImm(const ConstantInt *Val) const

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addMetadata(const MDNode *MD) const

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

Add a new virtual register operand.

const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const

bool isValid() const

Check for null.

Representation of each machine instruction.

void setHeapAllocMarker(MachineFunction &MF, MDNode *MD)

Set a marker on instructions that denotes where we should create and emit heap alloc site labels.

void eraseFromParent()

Unlink 'this' from the containing basic block and delete it.

void setPhysRegsDeadExcept(ArrayRef< Register > UsedRegs, const TargetRegisterInfo &TRI)

Mark every physreg used by this instruction as dead except those in the UsedRegs list.

A description of a memory reference used in the backend.

Flags

Flags values. These may be or'd together.

@ MOVolatile

The memory access is volatile.

@ MODereferenceable

The memory access is dereferenceable (i.e., doesn't trap).

@ MOLoad

The memory access reads data.

@ MONonTemporal

The memory access is non-temporal.

@ MOInvariant

The memory access always returns the same value (or traps).

@ MOStore

The memory access writes data.

MachineOperand class - Representation of each machine instruction operand.

static MachineOperand CreateRegMask(const uint32_t *Mask)

CreateRegMask - Creates a register mask operand referencing Mask.

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

static MachineOperand CreateImm(int64_t Val)

static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)

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)

static MachineOperand CreateFI(int Idx)

reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...

unsigned getOperandNo() const

getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.

const TargetRegisterClass * getRegClass(Register Reg) const

Return the register class of the specified virtual register.

reg_iterator reg_begin(Register RegNo) const

MachineInstr * getVRegDef(Register Reg) const

getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...

bool use_nodbg_empty(Register RegNo) const

use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.

Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")

createVirtualRegister - Create and return a new virtual register in the function with the specified r...

bool hasOneUse(Register RegNo) const

hasOneUse - Return true if there is exactly one instruction using the specified register.

ArrayRef< std::pair< MCRegister, Register > > liveins() const

const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)

constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...

void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const

Print the appropriate prefix and the specified global variable's name.

bool IsNewDbgInfoFormat

Is this Module using intrinsics to record the position of debugging information, or non-intrinsic rec...

Wrapper class representing virtual and physical registers.

static constexpr bool isVirtualRegister(unsigned Reg)

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

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

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.

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

TypeSize getElementOffset(unsigned Idx) const

Class to represent struct types.

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

unsigned getCallFrameDestroyOpcode() const

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

Provides information about what library functions are available for the current target.

bool hasOptimizedCodeGen(LibFunc F) const

Tests if the function is both available and a candidate for optimized code generation.

bool getLibFunc(StringRef funcName, LibFunc &F) const

Searches for a particular function name.

virtual Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const

Returns the desired alignment for ByVal or InAlloca aggregate function arguments in the caller parame...

EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const

Return the EVT corresponding to this LLVM type.

virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const

Return the register class that should be used for the specified value type.

virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const

Return the number of registers that this ValueType will eventually require.

virtual void markLibCallAttributes(MachineFunction *MF, unsigned CC, ArgListTy &Args) const

virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const

For types supported by the target, this is an identity function.

MVT getSimpleValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const

Return the MVT corresponding to this LLVM type. See getValueType.

bool isTypeLegal(EVT VT) const

Return true if the target has native support for the specified value type.

virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const

Return the pointer type for the given address space, defaults to the pointer type from the data layou...

MVT getRegisterType(MVT VT) const

Return the type of registers that this ValueType will eventually require.

virtual bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg, const DataLayout &DL) const

For some targets, an LLVM struct type must be broken down into multiple simple types,...

virtual const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const

Returns a 0 terminated array of registers that can be safely used as scratch registers.

virtual bool CanLowerReturn(CallingConv::ID, MachineFunction &, bool, const SmallVectorImpl< ISD::OutputArg > &, LLVMContext &, const Type *RetTy) const

This hook should be implemented to check whether the return values described by the Outs array can fi...

const Triple & getTargetTriple() const

unsigned NoTrapAfterNoreturn

Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...

unsigned TrapUnreachable

Emit target-specific trap instruction for 'unreachable' IR instructions.

virtual const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const

Returns the largest legal sub-class of RC that supports the sub-register index Idx.

virtual const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const

Return a mask of call-preserved registers for the given calling convention on the current function.

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

ArchType getArch() const

Get the parsed architecture type of this triple.

bool isOSAIX() const

Tests whether the OS is AIX.

bool isAArch64() const

Tests whether the target is AArch64 (little and big endian).

The instances of the Type class are immutable: once they are created, they are never changed.

static Type * getVoidTy(LLVMContext &C)

LLVMContext & getContext() const

Return the LLVMContext in which this type was uniqued.

Value * getOperand(unsigned i) const

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

bool hasOneUse() const

Return true if there is exactly one use of this value.

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

bool contains(const_arg_type_t< ValueT > V) const

Check if the set contains the given element.

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

const ParentTy * getParent() const

#define llvm_unreachable(msg)

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

@ AnyReg

OBSOLETED - Used for stack based JavaScript calls.

@ C

The default llvm calling convention, compatible with C.

@ ADD

Simple integer binary arithmetic operators.

@ SINT_TO_FP

[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...

@ FADD

Simple binary floating point operators.

@ BITCAST

BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...

@ SIGN_EXTEND

Conversion operators.

@ FNEG

Perform various unary floating-point operations inspired by libm.

@ SHL

Shift and rotation operations.

@ ZERO_EXTEND

ZERO_EXTEND - Used for integer types, zeroing the new bits.

@ FP_TO_SINT

FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.

@ AND

Bitwise operators - logical and, logical or, logical xor.

@ TRAP

TRAP - Trapping instruction.

@ TRUNCATE

TRUNCATE - Completely drop the high bits.

bool isBitwiseLogicOp(unsigned Opcode)

Whether this is bitwise logic opcode.

Reg

All possible values of the reg field in the ModR/M byte.

@ DW_OP_LLVM_arg

Only used in LLVM metadata.

const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get begin iterator over path.

reverse_iterator rend(StringRef path LLVM_LIFETIME_BOUND)

Get reverse end iterator over path.

This is an optimization pass for GlobalISel generic memory operations.

void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)

Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...

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

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

void diagnoseDontCall(const CallInst &CI)

auto successors(const MachineBasicBlock *BB)

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

Convenience function for iterating over sub-ranges.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

constexpr bool isPowerOf2_64(uint64_t Value)

Return true if the argument is a power of two > 0 (64 bit edition.)

gep_type_iterator gep_type_end(const User *GEP)

unsigned Log2_64(uint64_t Value)

Return the floor log base 2 of the specified value, -1 if the value is zero.

auto reverse(ContainerTy &&C)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM, bool ReturnsFirstArg=false)

Test if the given instruction is in a position to be optimized with a tail-call.

DWARFExpression::Operation Op

void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())

ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...

gep_type_iterator gep_type_begin(const User *GEP)

unsigned ComputeLinearIndex(Type *Ty, const unsigned *Indices, const unsigned *IndicesEnd, unsigned CurIndex=0)

Compute the linearized index of a member in a nested aggregate/struct/array.

PointerUnion< const Value *, const PseudoSourceValue * > ValueType

A collection of metadata nodes that might be associated with a memory access used by the alias-analys...

static constexpr roundingMode rmTowardZero

bool isSimple() const

Test if the given EVT is simple (as opposed to being extended).

bool bitsGT(EVT VT) const

Return true if this has more bits than VT.

bool bitsLT(EVT VT) const

Return true if this has less bits than VT.

TypeSize getSizeInBits() const

Return the size of the specified value type in bits.

static EVT getEVT(Type *Ty, bool HandleUnknown=false)

Return the value type corresponding to the specified type.

MVT getSimpleVT() const

Return the SimpleValueType held in the specified simple EVT.

static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)

Returns the EVT that represents an integer with the given number of bits.

SmallVector< ISD::ArgFlagsTy, 16 > OutFlags

SmallVector< Value *, 16 > OutVals

SmallVector< Register, 16 > OutRegs

CallLoweringInfo & setTailCall(bool Value=true)

SmallVector< Register, 4 > InRegs

CallLoweringInfo & setIsPatchPoint(bool Value=true)

CallLoweringInfo & setCallee(Type *ResultTy, FunctionType *FuncTy, const Value *Target, ArgListTy &&ArgsList, const CallBase &Call)

SmallVector< ISD::InputArg, 4 > Ins

InputArg - This struct carries flags and type information about a single incoming (formal) argument o...

This class contains a discriminated union of information about pointers in memory operands,...

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.