LLVM: lib/Target/X86/X86FlagsCopyLowering.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

53#include

54#include

55#include

56

57using namespace llvm;

58

59#define PASS_KEY "x86-flags-copy-lowering"

60#define DEBUG_TYPE PASS_KEY

61

62STATISTIC(NumCopiesEliminated, "Number of copies of EFLAGS eliminated");

63STATISTIC(NumSetCCsInserted, "Number of setCC instructions inserted");

64STATISTIC(NumTestsInserted, "Number of test instructions inserted");

65STATISTIC(NumAddsInserted, "Number of adds instructions inserted");

66STATISTIC(NumNFsConvertedTo, "Number of NF instructions converted to");

67

69

70namespace {

71

72

73using CondRegArray = std::array<Register, X86::LAST_VALID_COND + 1>;

74

76public:

78

79 StringRef getPassName() const override { return "X86 EFLAGS copy lowering"; }

80 bool runOnMachineFunction(MachineFunction &MF) override;

81 void getAnalysisUsage(AnalysisUsage &AU) const override;

82

83

84 static char ID;

85

86private:

87 MachineRegisterInfo *MRI = nullptr;

88 const X86Subtarget *Subtarget = nullptr;

89 const X86InstrInfo *TII = nullptr;

90 const TargetRegisterInfo *TRI = nullptr;

91 const TargetRegisterClass *PromoteRC = nullptr;

92 MachineDominatorTree *MDT = nullptr;

93

94 CondRegArray collectCondsInRegs(MachineBasicBlock &MBB,

96

97 Register promoteCondToReg(MachineBasicBlock &MBB,

100 std::pair<Register, bool> getCondOrInverseInReg(

105

107 const DebugLoc &Loc, MachineInstr &MI,

108 CondRegArray &CondRegs);

109 void rewriteArithmetic(MachineBasicBlock &MBB,

111 MachineInstr &MI, CondRegArray &CondRegs);

113 const DebugLoc &Loc, MachineInstr &MI, CondRegArray &CondRegs);

114};

115

116}

117

119 "X86 EFLAGS copy lowering", false, false)

122

124 return new X86FlagsCopyLoweringPass();

125}

126

127char X86FlagsCopyLoweringPass::ID = 0;

128

129void X86FlagsCopyLoweringPass::getAnalysisUsage(AnalysisUsage &AU) const {

132}

133

135 return X86::isADC(Opc) || X86::isSBB(Opc) || X86::isRCL(Opc) ||

136 X86::isRCR(Opc) || (Opc == X86::SETB_C32r || Opc == X86::SETB_C64r);

137}

138

143

145 "Split instruction must be in the split block!");

147 "Only designed to split a tail of branch instructions!");

149 "Must split on an actual jCC instruction!");

150

151

153 assert(PrevI.isBranch() && "Must split after a branch!");

155 "Must split after an actual jCC instruction!");

157 "Must only have this one terminator prior to the split!");

158

159

161

162

163

164

165 bool IsEdgeSplit =

168 assert(MI.isTerminator() &&

169 "Should only have spliced terminators!");

170 return llvm::any_of(

171 MI.operands(), [&](MachineOperand &MOp) {

172 return MOp.isMBB() && MOp.getMBB() == &UnsplitSucc;

173 });

174 }) ||

176

177 MachineBasicBlock &NewMBB = *MF.CreateMachineBasicBlock();

178

179

180

182

183

185

186

187

189 if (IsEdgeSplit || *SI != &UnsplitSucc)

191

192 if (!IsEdgeSplit)

194

195

196

197 for (MachineBasicBlock *Succ : NewMBB.successors())

198 if (Succ != &UnsplitSucc)

199 MBB.replaceSuccessor(Succ, &NewMBB);

200

201

203 "Failed to make the new block a successor!");

204

205

206 for (MachineBasicBlock *Succ : NewMBB.successors()) {

207 for (MachineInstr &MI : *Succ) {

208 if (MI.isPHI())

209 break;

210

213 MachineOperand &OpV = MI.getOperand(OpIdx);

214 MachineOperand &OpMBB = MI.getOperand(OpIdx + 1);

215 assert(OpMBB.isMBB() && "Block operand to a PHI is not a block!");

217 continue;

218

219

220 if (!IsEdgeSplit || Succ != &UnsplitSucc) {

221 OpMBB.setMBB(&NewMBB);

222

223

224

225 continue;

226 }

227

228

229 MI.addOperand(MF, OpV);

231 break;

232 }

233 }

234 }

235

236 return NewMBB;

237}

238

240

243 MI.findRegisterDefOperand(X86::EFLAGS, nullptr);

244 if (!FlagDef)

246

247

248

249

250

251 bool IsWithReloc =

253

256

258}

259

260bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {

262 << " **********\n");

263

264 Subtarget = &MF.getSubtarget();

268 PromoteRC = &X86::GR8RegClass;

269

271

272 return false;

273

274 if (none_of(MRI->def_instructions(X86::EFLAGS), [](const MachineInstr &MI) {

275 return MI.getOpcode() == TargetOpcode::COPY;

276 }))

277 return false;

278

279

280

281

282

283

284 auto MDTWrapper = getAnalysisIfAvailable();

285 std::unique_ptr OwnedMDT;

286 if (MDTWrapper) {

287 MDT = &MDTWrapper->getDomTree();

288 } else {

289 OwnedMDT = std::make_unique(MF);

290 MDT = OwnedMDT.get();

291 }

292

293

294

295

296

297 SmallSetVector<MachineInstr *, 4> Copies;

298 ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);

299 for (MachineBasicBlock *MBB : RPOT)

300 for (MachineInstr &MI : *MBB)

301 if (MI.getOpcode() == TargetOpcode::COPY &&

302 MI.getOperand(0).getReg() == X86::EFLAGS)

304

305

306

307

308

309

310

311

312

313

314

315

316

317 if (Subtarget->hasNF()) {

318 SmallSetVector<MachineInstr *, 4> RemovedCopies;

319

320 auto CopyIIt = Copies.begin(), CopyIEnd = Copies.end();

321 while (CopyIIt != CopyIEnd) {

322 auto NCopyIIt = std::next(CopyIIt);

323 SmallSetVector<MachineInstr *, 4> EvitableClobbers;

324 MachineInstr *CopyI = *CopyIIt;

325 MachineOperand &VOp = CopyI->getOperand(1);

326 MachineInstr *CopyDefI = MRI->getVRegDef(VOp.getReg());

327 MachineBasicBlock *CopyIMBB = CopyI->getParent();

328 MachineBasicBlock *CopyDefIMBB = CopyDefI->getParent();

329

330

331

332

333

334 for (auto BI = idf_begin(CopyIMBB), BE = idf_end(CopyDefIMBB); BI != BE;

335 ++BI) {

336 MachineBasicBlock *MBB = *BI;

337 for (auto I = (MBB != CopyDefIMBB)

342 I != E; ++I) {

343 MachineInstr &MI = *I;

346 continue;

347

349 goto ProcessNextCopyI;

350

352 EvitableClobbers.insert(&MI);

353 }

354 }

355

356 RemovedCopies.insert(CopyI);

359 RemovedCopies.insert(CopyDefI);

361 }

362 ++NumCopiesEliminated;

363 for (auto *Clobber : EvitableClobbers) {

365 assert(NewOpc && "evitable clobber must have a NF variant");

366 Clobber->setDesc(TII->get(NewOpc));

367 Clobber->removeOperand(

368 Clobber->findRegisterDefOperand(X86::EFLAGS, nullptr)

369 ->getOperandNo());

370 ++NumNFsConvertedTo;

371 }

372

373 for (auto BI = idf_begin(CopyIMBB), BE = idf_end(CopyDefIMBB); BI != BE;

374 ++BI)

375 if (*BI != CopyDefIMBB)

376 BI->addLiveIn(X86::EFLAGS);

377 ProcessNextCopyI:

378 CopyIIt = NCopyIIt;

379 }

380 Copies.set_subtract(RemovedCopies);

381 }

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398 for (MachineInstr *CopyI : Copies) {

399 MachineBasicBlock &MBB = *CopyI->getParent();

400

401 MachineOperand &VOp = CopyI->getOperand(1);

403 "The input to the copy for EFLAGS should always be a register!");

404 MachineInstr &CopyDefI = *MRI->getVRegDef(VOp.getReg());

405 if (CopyDefI.getOpcode() != TargetOpcode::COPY) {

406

407

408

409

410

411

412

413

414

415

416

417

418

419

421 dbgs() << "ERROR: Encountered unexpected def of an eflags copy: ";

422 CopyDefI.dump());

424 "Cannot lower EFLAGS copy unless it is defined in turn by a copy!");

425 }

426

428

429

433 ++NumCopiesEliminated;

434 });

435

436 MachineOperand &DOp = CopyI->getOperand(0);

437 assert(DOp.isDef() && "Expected register def!");

438 assert(DOp.getReg() == X86::EFLAGS && "Unexpected copy def register!");

439 if (DOp.isDead())

440 continue;

441

442 MachineBasicBlock *TestMBB = CopyDefI.getParent();

445

447

448

449

450

451

452

453

454

455

456

457

460

461

464

465

466 return &MI != CopyI &&

467 MI.findRegisterDefOperand(X86::EFLAGS, nullptr);

468 });

469 };

470 auto HasEFLAGSClobberPath = [&](MachineBasicBlock *BeginMBB,

471 MachineBasicBlock *EndMBB) {

473 "Only support paths down the dominator tree!");

474 SmallPtrSet<MachineBasicBlock *, 4> Visited;

475 SmallVector<MachineBasicBlock *, 4> Worklist;

476

477 Visited.insert(BeginMBB);

479 do {

482 if (!Visited.insert(PredMBB).second)

483 continue;

484 if (HasEFLAGSClobber(PredMBB->begin(), PredMBB->end()))

485 return true;

486

488 }

489 } while (!Worklist.empty());

490

491 return false;

492 };

494 !HasEFLAGSClobber(TestMBB->begin(), TestPos)) {

495

496

497 MachineBasicBlock *HoistMBB =

498 std::accumulate(std::next(TestMBB->pred_begin()), TestMBB->pred_end(),

500 [&](MachineBasicBlock *LHS, MachineBasicBlock *RHS) {

501 return MDT->findNearestCommonDominator(LHS, RHS);

502 });

503

504

505

506

507 if (HasEFLAGSClobberPath(HoistMBB, TestMBB))

508 break;

509

510

513 break;

514

515

516 TestMBB = HoistMBB;

518

520 }

524 [&](MachineInstr &MI) {

525 return MI.findRegisterDefOperand(X86::EFLAGS, nullptr);

526 });

527 if (DefIt.base() != TestMBB->instr_begin()) {

528 dbgs() << " Using EFLAGS defined by: ";

529 DefIt->dump();

530 } else {

531 dbgs() << " Using live-in flags for BB:\n";

532 TestMBB->dump();

533 }

534 });

535

536

537

538

539 SmallVector<MachineInstr *, 4> JmpIs;

540

541

542

543

544

545

546 CondRegArray CondRegs = collectCondsInRegs(*TestMBB, TestPos);

547

548

549

550

552 SmallPtrSet<MachineBasicBlock *, 2> VisitedBlocks;

554

555 do {

556 MachineBasicBlock &UseMBB = *Blocks.pop_back_val();

557

558

559 bool FlagsKilled = false;

560

561

562

563

564

565

566

567

568

569

574 MII != MIE;) {

575 MachineInstr &MI = *MII++;

576

577

578

579

580 if (&MI == CopyI || &MI == &CopyDefI) {

582 "Should only encounter these on the second pass over the "

583 "original block.");

584 break;

585 }

586

587 MachineOperand *FlagUse =

588 MI.findRegisterUseOperand(X86::EFLAGS, nullptr);

589 FlagsKilled = MI.modifiesRegister(X86::EFLAGS, TRI);

590

591 if (!FlagUse && FlagsKilled)

592 break;

593 else if (!FlagUse)

594 continue;

595

597

598

599 if (FlagUse->isKill())

600 FlagsKilled = true;

601

602

603

604

605

606

607

608

609

611 auto JmpIt = MI.getIterator();

612 do {

613 JmpIs.push_back(&*JmpIt);

614 ++JmpIt;

615 } while (JmpIt != UseMBB.instr_end() &&

617 break;

618 }

619

620

621 unsigned Opc = MI.getOpcode();

622 if (Opc == TargetOpcode::COPY) {

623

624 MRI->replaceRegWith(MI.getOperand(0).getReg(),

626 MI.eraseFromParent();

627 } else if (X86::isSETCC(Opc) || X86::isSETZUCC(Opc)) {

628 rewriteSetCC(*TestMBB, TestPos, TestLoc, MI, CondRegs);

630 rewriteArithmetic(*TestMBB, TestPos, TestLoc, MI, CondRegs);

631 } else {

632 rewriteMI(*TestMBB, TestPos, TestLoc, MI, CondRegs);

633 }

634

635

636 if (FlagsKilled)

637 break;

638 }

639

640

641 if (FlagsKilled)

642 continue;

643

644

645

646 for (MachineBasicBlock *SuccMBB : UseMBB.successors())

647 if (SuccMBB->isLiveIn(X86::EFLAGS) &&

649

650

651

652

653

654

655

656

657

658

659

660

661

662 if (SuccMBB == TestMBB || !MDT->dominates(TestMBB, SuccMBB)) {

665 << "ERROR: Encountered use that is not dominated by our test "

666 "basic block! Rewriting this would require inserting PHI "

667 "nodes to track the flag state across the CFG.\n\nTest "

668 "block:\n";

669 TestMBB->dump();

670 dbgs() << "Use block:\n";

671 SuccMBB->dump();

672 });

674 "Cannot lower EFLAGS copy when original copy def "

675 "does not dominate all uses.");

676 }

677

679

680

681 SuccMBB->removeLiveIn(X86::EFLAGS);

682 }

683 } while (!Blocks.empty());

684

685

686

687

688 MachineBasicBlock *LastJmpMBB = nullptr;

689 for (MachineInstr *JmpI : JmpIs) {

690

691

692 if (JmpI->getParent() == LastJmpMBB)

694 else

696

697 rewriteMI(*TestMBB, TestPos, TestLoc, *JmpI, CondRegs);

698 }

699

700

701

702 }

703

704#ifndef NDEBUG

705 for (MachineBasicBlock &MBB : MF)

706 for (MachineInstr &MI : MBB)

707 if (MI.getOpcode() == TargetOpcode::COPY &&

708 (MI.getOperand(0).getReg() == X86::EFLAGS ||

709 MI.getOperand(1).getReg() == X86::EFLAGS)) {

710 LLVM_DEBUG(dbgs() << "ERROR: Found a COPY involving EFLAGS: ";

713 }

714#endif

715

716 return true;

717}

718

719

720

721CondRegArray X86FlagsCopyLoweringPass::collectCondsInRegs(

723 CondRegArray CondRegs = {};

724

725

726 for (MachineInstr &MI :

730 MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isVirtual()) {

731 assert(MI.getOperand(0).isDef() &&

732 "A non-storing SETcc should always define a register!");

733 CondRegs[Cond] = MI.getOperand(0).getReg();

734 }

735

736

737

738 if (MI.findRegisterDefOperand(X86::EFLAGS, nullptr))

739 break;

740 }

741 return CondRegs;

742}

743

744Register X86FlagsCopyLoweringPass::promoteCondToReg(

747 Register Reg = MRI->createVirtualRegister(PromoteRC);

748 auto SetI = BuildMI(TestMBB, TestPos, TestLoc, TII->get(X86::SETCCr), Reg)

750 (void)SetI;

752 ++NumSetCCsInserted;

753 return Reg;

754}

755

756std::pair<Register, bool> X86FlagsCopyLoweringPass::getCondOrInverseInReg(

761 if (!CondReg && !InvCondReg)

762 CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);

763

764 if (CondReg)

765 return {CondReg, false};

766 else

767 return {InvCondReg, true};

768}

769

770void X86FlagsCopyLoweringPass::insertTest(MachineBasicBlock &MBB,

773 auto TestI =

775 (void)TestI;

777 ++NumTestsInserted;

778}

779

780void X86FlagsCopyLoweringPass::rewriteSetCC(MachineBasicBlock &MBB,

783 MachineInstr &MI,

784 CondRegArray &CondRegs) {

786

787

788

790 if (!CondReg)

791 CondReg = promoteCondToReg(MBB, Pos, Loc, Cond);

792

793 if (X86::isSETZUCC(MI.getOpcode())) {

794

795 assert(MI.mayStore() && "Cannot handle memory variants");

796 assert(MI.getOperand(0).isReg() &&

797 "Cannot have a non-register defined operand to SETZUcc!");

798 Register OldReg = MI.getOperand(0).getReg();

799

800

801 MRI->clearKillFlags(OldReg);

802 for (auto &Use : MRI->use_instructions(OldReg)) {

803 assert(Use.getOpcode() == X86::INSERT_SUBREG &&

804 "SETZUCC should be only used by INSERT_SUBREG");

805 Use.getOperand(2).setReg(CondReg);

806

807 Register ZeroReg = MRI->createVirtualRegister(&X86::GR32RegClass);

808 BuildMI(*Use.getParent(), &Use, Use.getDebugLoc(), TII->get(X86::MOV32r0),

809 ZeroReg);

810 Use.getOperand(1).setReg(ZeroReg);

811 }

812 MI.eraseFromParent();

813 return;

814 }

815

816

817

818 if (MI.mayStore()) {

819 assert(MI.getOperand(0).isReg() &&

820 "Cannot have a non-register defined operand to SETcc!");

821 Register OldReg = MI.getOperand(0).getReg();

822

823

824 MRI->clearKillFlags(OldReg);

825 MRI->replaceRegWith(OldReg, CondReg);

826 MI.eraseFromParent();

827 return;

828 }

829

830

831 auto MIB = BuildMI(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(),

832 TII->get(X86::MOV8mr));

833

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

836

837 MIB.addReg(CondReg);

838 MIB.setMemRefs(MI.memoperands());

839 MI.eraseFromParent();

840}

841

842void X86FlagsCopyLoweringPass::rewriteArithmetic(

844 const DebugLoc &Loc, MachineInstr &MI, CondRegArray &CondRegs) {

845

847

848

849

850 int Addend = 255;

851

852

853

854

856 if (!CondReg)

857 CondReg = promoteCondToReg(MBB, Pos, Loc, Cond);

858

859

860 Register TmpReg = MRI->createVirtualRegister(PromoteRC);

861 auto AddI =

862 BuildMI(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(),

863 TII->get(Subtarget->hasNDD() ? X86::ADD8ri_ND : X86::ADD8ri))

867 (void)AddI;

869 ++NumAddsInserted;

870 MI.findRegisterUseOperand(X86::EFLAGS, nullptr)->setIsKill(true);

871}

872

874#define FROM_TO(A, B) \

875 case X86::CMOV##A##_Fp32: \

876 case X86::CMOV##A##_Fp64: \

877 case X86::CMOV##A##_Fp80: \

878 return X86::COND_##B;

879

880 switch (Opc) {

881 default:

891 }

892#undef FROM_TO

893}

894

897#define CASE(A) \

898 case X86::CMOVB_##A: \

899 case X86::CMOVE_##A: \

900 case X86::CMOVP_##A: \

901 case X86::CMOVBE_##A: \

902 case X86::CMOVNB_##A: \

903 case X86::CMOVNE_##A: \

904 case X86::CMOVNP_##A: \

905 case X86::CMOVNBE_##A: \

906 return (CC == X86::COND_E) ? X86::CMOVE_##A : X86::CMOVNE_##A;

907 switch (Opc) {

908 default:

913 }

914#undef CASE

915}

916

917void X86FlagsCopyLoweringPass::rewriteMI(MachineBasicBlock &MBB,

919 const DebugLoc &Loc, MachineInstr &MI,

920 CondRegArray &CondRegs) {

921

922 bool IsImplicitCC = false;

926 IsImplicitCC = true;

927 }

930 bool Inverted;

931 std::tie(CondReg, Inverted) =

932 getCondOrInverseInReg(MBB, Pos, Loc, CC, CondRegs);

933

934

935 insertTest(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(), CondReg);

936

937

938

940 if (IsImplicitCC)

942 else

943 MI.getOperand(MI.getDesc().getNumOperands() - 1).setImm(NewCC);

944

945 MI.findRegisterUseOperand(X86::EFLAGS, nullptr)->setIsKill(true);

947}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

#define CASE(ATTRNAME, AANAME,...)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks

This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.

static const HTTPClientCleanup Cleanup

const size_t AbstractManglingParser< Derived, Alloc >::NumOps

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

Register const TargetRegisterInfo * TRI

Promote Memory to Register

MachineInstr unsigned OpIdx

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.

const SmallVectorImpl< MachineOperand > & Cond

static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI, MachineDominatorTree *MDT)

This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...

This file defines the SmallPtrSet 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)

#define FROM_TO(FROM, TO)

cl::opt< bool > X86EnableAPXForRelocation

static X86::CondCode getImplicitCondFromMI(unsigned Opc)

Definition X86FlagsCopyLowering.cpp:873

EFLAGSClobber

Definition X86FlagsCopyLowering.cpp:239

@ InevitableClobber

Definition X86FlagsCopyLowering.cpp:239

@ NoClobber

Definition X86FlagsCopyLowering.cpp:239

@ EvitableClobber

Definition X86FlagsCopyLowering.cpp:239

static unsigned getOpcodeWithCC(unsigned Opc, X86::CondCode CC)

Definition X86FlagsCopyLowering.cpp:895

static bool isArithmeticOp(unsigned Opc)

Definition X86FlagsCopyLowering.cpp:134

static EFLAGSClobber getClobberType(const MachineInstr &MI)

Definition X86FlagsCopyLowering.cpp:241

Represent the analysis usage information of a pass.

AnalysisUsage & addUsedIfAvailable()

Add the specified Pass class to the set of analyses used by this pass.

FunctionPass class - This class is used to implement most global optimizations.

const MCInstrDesc & get(unsigned Opcode) const

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

void normalizeSuccProbs()

Normalize probabilities of all successors so that the sum of them becomes one.

instr_iterator instr_begin()

LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)

Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...

LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)

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

succ_iterator succ_begin()

LLVM_ABI iterator getFirstTerminator()

Returns an iterator to the first terminator instruction of this basic block.

LLVM_ABI void dump() const

LLVM_ABI void copySuccessor(const MachineBasicBlock *Orig, succ_iterator I)

Copy a successor (and any probability info) from original block to this block's.

pred_iterator pred_begin()

instr_iterator instr_end()

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

iterator_range< succ_iterator > successors()

LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB is a successor of this block.

iterator_range< pred_iterator > predecessors()

void splice(iterator Where, MachineBasicBlock *Other, iterator From)

Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...

MachineInstrBundleIterator< MachineInstr > iterator

LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const

Return true if the specified register is in the live in set.

Analysis pass which computes a MachineDominatorTree.

bool dominates(const MachineInstr *A, const MachineInstr *B) const

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

BasicBlockListType::iterator iterator

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

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

Add a new virtual register operand.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

bool isBranch(QueryType Type=AnyInBundle) const

Returns true if this is a conditional, unconditional, or indirect branch.

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

LLVM_ABI void eraseFromParent()

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

LLVM_ABI void dump() const

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

void setMBB(MachineBasicBlock *MBB)

Register getReg() const

getReg - Returns the register number.

static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)

bool isMBB() const

isMBB - Tests if this is a MO_MachineBasicBlock operand.

bool insert(const value_type &X)

Insert a new element into the SetVector.

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

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

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

void push_back(const T &Elt)

const X86InstrInfo * getInstrInfo() const override

const X86RegisterInfo * getRegisterInfo() const override

self_iterator getIterator()

#define llvm_unreachable(msg)

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

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

CondCode getCondFromBranch(const MachineInstr &MI)

CondCode getCondFromMI(const MachineInstr &MI)

Return the condition code of the instruction.

CondCode GetOppositeBranchCondition(CondCode CC)

GetOppositeBranchCondition - Return the inverse of the specified cond, e.g.

CondCode getCondFromSETCC(const MachineInstr &MI)

unsigned getNFVariant(unsigned Opc)

NodeAddr< UseNode * > Use

This is an optimization pass for GlobalISel generic memory operations.

static bool isAddMemInstrWithRelocation(const MachineInstr &MI)

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

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

detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)

auto successors(const MachineBasicBlock *BB)

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

Convenience function for iterating over sub-ranges.

FunctionPass * createX86FlagsCopyLoweringPass()

Return a pass that lowers EFLAGS copy pseudo instructions.

Definition X86FlagsCopyLowering.cpp:123

bool any_of(R &&range, UnaryPredicate P)

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

auto reverse(ContainerTy &&C)

LLVM_ABI raw_ostream & dbgs()

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

bool none_of(R &&Range, UnaryPredicate P)

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

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

idf_iterator< T > idf_end(const T &G)

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

idf_iterator< T > idf_begin(const T &G)

auto find_if(R &&Range, UnaryPredicate P)

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