LLVM: lib/Target/AMDGPU/SILowerControlFlow.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

41

42

43

44

45

46

47

48

49

50

63

64using namespace llvm;

65

66#define DEBUG_TYPE "si-lower-control-flow"

67

71

72namespace {

73

74class SILowerControlFlow {

75private:

87

90

91 bool EnableOptimizeEndCf = false;

92

94

99

101

102 void findMaskOperands(MachineInstr &MI, unsigned OpNo,

104

106

108

110

111

112

113

117

118

122 assert(I->isTerminator());

123

124

126 while (I != End && I->isUnconditionalBranch())

127 ++I;

128 return I;

129 }

130

131

132 void optimizeEndCf();

133

134public:

135 SILowerControlFlow(const GCNSubtarget *ST, LiveIntervals *LIS,

136 LiveVariables *LV, MachineDominatorTree *MDT,

137 MachinePostDominatorTree *PDT)

138 : LIS(LIS), LV(LV), MDT(MDT), PDT(PDT),

139 LMC(AMDGPU::LaneMaskConstants::get(*ST)) {}

140 bool run(MachineFunction &MF);

141};

142

144public:

145 static char ID;

146

147 SILowerControlFlowLegacy() : MachineFunctionPass(ID) {}

148

149 bool runOnMachineFunction(MachineFunction &MF) override;

150

151 StringRef getPassName() const override {

152 return "SI Lower control flow pseudo instructions";

153 }

154

155 void getAnalysisUsage(AnalysisUsage &AU) const override {

157

158 AU.addPreserved();

159 AU.addPreserved();

164 }

165};

166

167}

168

169char SILowerControlFlowLegacy::ID = 0;

170

172 false, false)

173

177

179}

180

182

187

188 while (!Worklist.empty()) {

190

191 if (MBB == End || !Visited.insert(MBB).second)

192 continue;

194 return true;

195

196 Worklist.append(MBB->succ_begin(), MBB->succ_end());

197 }

198

199 return false;

200}

201

203 Register SaveExecReg = MI.getOperand(0).getReg();

204 auto U = MRI->use_instr_nodbg_begin(SaveExecReg);

205

206 if (U == MRI->use_instr_nodbg_end() ||

207 std::next(U) != MRI->use_instr_nodbg_end() ||

208 U->getOpcode() != AMDGPU::SI_END_CF)

209 return false;

210

211 return true;

212}

213

214void SILowerControlFlow::emitIf(MachineInstr &MI) {

215 MachineBasicBlock &MBB = *MI.getParent();

218 Register SaveExecReg = MI.getOperand(0).getReg();

219 MachineOperand& Cond = MI.getOperand(1);

220 assert(Cond.getSubReg() == AMDGPU::NoSubRegister);

221

222 MachineOperand &ImpDefSCC = MI.getOperand(4);

224

225

226

227

229

230 if (SimpleIf) {

231

232

233 auto UseMI = MRI->use_instr_nodbg_begin(SaveExecReg);

235 }

236

237

238

239 Register CopyReg = SimpleIf ? SaveExecReg

240 : MRI->createVirtualRegister(BoolRC);

241 MachineInstr *CopyExec = BuildMI(MBB, I, DL, TII->get(AMDGPU::COPY), CopyReg)

244 LoweredIf.insert(CopyReg);

245

246 Register Tmp = MRI->createVirtualRegister(BoolRC);

247

248 MachineInstr *And =

250 if (LV)

252

253 setImpSCCDefDead(*And, true);

254

255 MachineInstr *Xor = nullptr;

256 if (!SimpleIf) {

260 setImpSCCDefDead(*Xor, ImpDefSCC.isDead());

261 }

262

263

264

265 MachineInstr *SetExec =

268 if (LV)

270

271

272

273 I = skipToUncondBrOrEnd(MBB, I);

274

275

276

277 MachineInstr *NewBr = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_CBRANCH_EXECZ))

278 .add(MI.getOperand(2));

279

280 if (!LIS) {

281 MI.eraseFromParent();

282 return;

283 }

284

286

287

288

290

291 if (!SimpleIf)

295

296 MI.eraseFromParent();

297

298

299

300

301 RecomputeRegs.insert(SaveExecReg);

303 if (!SimpleIf)

305}

306

307void SILowerControlFlow::emitElse(MachineInstr &MI) {

308 MachineBasicBlock &MBB = *MI.getParent();

310

311 Register DstReg = MI.getOperand(0).getReg();

312 Register SrcReg = MI.getOperand(1).getReg();

313

315

316

317

318 Register SaveReg = MRI->createVirtualRegister(BoolRC);

319 MachineInstr *OrSaveExec =

321 .add(MI.getOperand(1));

322 if (LV)

324

325 MachineBasicBlock *DestBB = MI.getOperand(2).getMBB();

326

328

329

330

334

335 MachineInstr *Xor =

339

340

341

342 ElsePt = skipToUncondBrOrEnd(MBB, ElsePt);

343

344 MachineInstr *Branch =

347

348 if (!LIS) {

349 MI.eraseFromParent();

350 return;

351 }

352

354 MI.eraseFromParent();

355

358

361

362 RecomputeRegs.insert(SrcReg);

363 RecomputeRegs.insert(DstReg);

365}

366

367void SILowerControlFlow::emitIfBreak(MachineInstr &MI) {

368 MachineBasicBlock &MBB = *MI.getParent();

370 auto Dst = MI.getOperand(0).getReg();

371

372

373

374

375

376 bool SkipAnding = false;

377 if (MI.getOperand(1).isReg()) {

378 if (MachineInstr *Def = MRI->getUniqueVRegDef(MI.getOperand(1).getReg())) {

379 SkipAnding = Def->getParent() == MI.getParent()

381 }

382 }

383

384

385

386 MachineInstr *And = nullptr, *Or = nullptr;

388 if (!SkipAnding) {

389 AndReg = MRI->createVirtualRegister(BoolRC);

392 .add(MI.getOperand(1));

393 if (LV)

397 .add(MI.getOperand(2));

398 } else {

400 .add(MI.getOperand(1))

401 .add(MI.getOperand(2));

402 if (LV)

404 }

405 if (LV)

407

408 if (LIS) {

410 if (And) {

411

412 RecomputeRegs.insert(And->getOperand(2).getReg());

415 }

416 }

417

418 MI.eraseFromParent();

419}

420

421void SILowerControlFlow::emitLoop(MachineInstr &MI) {

422 MachineBasicBlock &MBB = *MI.getParent();

424

425 MachineInstr *AndN2 =

428 .add(MI.getOperand(0));

429 if (LV)

431

432 auto BranchPt = skipToUncondBrOrEnd(MBB, MI.getIterator());

433 MachineInstr *Branch =

435 .add(MI.getOperand(1));

436

437 if (LIS) {

438 RecomputeRegs.insert(MI.getOperand(0).getReg());

441 }

442

443 MI.eraseFromParent();

444}

445

447SILowerControlFlow::skipIgnoreExecInstsTrivialSucc(

449

450 SmallPtrSet<const MachineBasicBlock *, 4> Visited;

451 MachineBasicBlock *B = &MBB;

452 do {

453 if (!Visited.insert(B).second)

455

456 auto E = B->end();

457 for ( ; It != E; ++It) {

458 if (TII->mayReadEXEC(*MRI, *It))

459 break;

460 }

461

462 if (It != E)

463 return It;

464

465 if (B->succ_size() != 1)

467

468

469 MachineBasicBlock *Succ = *B->succ_begin();

470

471 It = Succ->begin();

472 B = Succ;

473 } while (true);

474}

475

476MachineBasicBlock *SILowerControlFlow::emitEndCf(MachineInstr &MI) {

477 MachineBasicBlock &MBB = *MI.getParent();

479

481

482

483

484

485 bool NeedBlockSplit = false;

486 Register DataReg = MI.getOperand(0).getReg();

488 I != E; ++I) {

489 if (I->modifiesRegister(DataReg, TRI)) {

490 NeedBlockSplit = true;

491 break;

492 }

493 }

494

495 unsigned Opcode = LMC.OrOpc;

496 MachineBasicBlock *SplitBB = &MBB;

497 if (NeedBlockSplit) {

498 SplitBB = MBB.splitAt(MI, true, LIS);

499 if (SplitBB != &MBB && (MDT || PDT)) {

502 for (MachineBasicBlock *Succ : SplitBB->successors()) {

503 DTUpdates.push_back({DomTreeT::Insert, SplitBB, Succ});

504 DTUpdates.push_back({DomTreeT::Delete, &MBB, Succ});

505 }

506 DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB});

507 if (MDT)

509 if (PDT)

511 }

513 InsPt = MI;

514 }

515

518 .add(MI.getOperand(0));

519 if (LV) {

521

522 if (SplitBB != &MBB) {

523

524

525

526

527 DenseSet DefInOrigBlock;

528

529 for (MachineBasicBlock *BlockPiece : {&MBB, SplitBB}) {

530 for (MachineInstr &X : *BlockPiece) {

531 for (MachineOperand &Op : X.all_defs()) {

532 if (Op.getReg().isVirtual())

533 DefInOrigBlock.insert(Op.getReg());

534 }

535 }

536 }

537

538 for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {

539 Register Reg = Register::index2VirtReg(i);

541

543 VI.AliveBlocks.set(SplitBB->getNumber());

544 else {

545 for (MachineInstr *Kill : VI.Kills) {

546 if (Kill->getParent() == SplitBB && !DefInOrigBlock.contains(Reg))

548 }

549 }

550 }

551 }

552 }

553

554 LoweredEndCf.insert(NewMI);

555

556 if (LIS)

558

559 MI.eraseFromParent();

560

561 if (LIS)

563 return SplitBB;

564}

565

566

567

568void SILowerControlFlow::findMaskOperands(MachineInstr &MI, unsigned OpNo,

569 SmallVectorImpl &Src) const {

570 MachineOperand &Op = MI.getOperand(OpNo);

571 if (Op.isReg() || Op.getReg().isVirtual()) {

572 Src.push_back(Op);

573 return;

574 }

575

576 MachineInstr *Def = MRI->getUniqueVRegDef(Op.getReg());

577 if (!Def || Def->getParent() != MI.getParent() ||

578 !(Def->isFullCopy() || (Def->getOpcode() == MI.getOpcode())))

579 return;

580

581

582

583

584 for (auto I = Def->getIterator(); I != MI.getIterator(); ++I)

585 if (I->modifiesRegister(AMDGPU::EXEC, TRI) &&

586 !(I->isCopy() && I->getOperand(0).getReg() != LMC.ExecReg))

587 return;

588

589 for (const auto &SrcOp : Def->explicit_operands())

590 if (SrcOp.isReg() && SrcOp.isUse() &&

591 (SrcOp.getReg().isVirtual() || SrcOp.getReg() == LMC.ExecReg))

592 Src.push_back(SrcOp);

593}

594

595

596

597

598

599void SILowerControlFlow::combineMasks(MachineInstr &MI) {

600 assert(MI.getNumExplicitOperands() == 3);

602 unsigned OpToReplace = 1;

603 findMaskOperands(MI, 1, Ops);

604 if (Ops.size() == 1) OpToReplace = 2;

605 findMaskOperands(MI, 2, Ops);

606 if (Ops.size() != 3) return;

607

608 unsigned UniqueOpndIdx;

609 if (Ops[0].isIdenticalTo(Ops[1])) UniqueOpndIdx = 2;

610 else if (Ops[0].isIdenticalTo(Ops[2])) UniqueOpndIdx = 1;

611 else if (Ops[1].isIdenticalTo(Ops[2])) UniqueOpndIdx = 1;

612 else return;

613

614 Register Reg = MI.getOperand(OpToReplace).getReg();

615 MI.removeOperand(OpToReplace);

616 MI.addOperand(Ops[UniqueOpndIdx]);

617 if (MRI->use_empty(Reg))

618 MRI->getUniqueVRegDef(Reg)->eraseFromParent();

619}

620

621void SILowerControlFlow::optimizeEndCf() {

622

623

624 if (!EnableOptimizeEndCf)

625 return;

626

627 for (MachineInstr *MI : reverse(LoweredEndCf)) {

628 MachineBasicBlock &MBB = *MI->getParent();

630 skipIgnoreExecInstsTrivialSucc(MBB, std::next(MI->getIterator()));

632 continue;

633

634

636 = TII->getNamedOperand(*Next, AMDGPU::OpName::src1)->getReg();

637 assert(SavedExec.isVirtual() && "Expected saved exec to be src1!");

638

639 const MachineInstr *Def = MRI->getUniqueVRegDef(SavedExec);

640 if (Def && LoweredIf.count(SavedExec)) {

642 if (LIS)

645 if (LV)

646 Reg = TII->getNamedOperand(*MI, AMDGPU::OpName::src1)->getReg();

647 MI->eraseFromParent();

648 if (LV)

650 removeMBBifRedundant(MBB);

651 }

652 }

653}

654

655MachineBasicBlock *SILowerControlFlow::process(MachineInstr &MI) {

656 MachineBasicBlock &MBB = *MI.getParent();

658 MachineInstr *Prev = (I != MBB.begin()) ? &*(std::prev(I)) : nullptr;

659

660 MachineBasicBlock *SplitBB = &MBB;

661

662 switch (MI.getOpcode()) {

663 case AMDGPU::SI_IF:

664 emitIf(MI);

665 break;

666

667 case AMDGPU::SI_ELSE:

668 emitElse(MI);

669 break;

670

671 case AMDGPU::SI_IF_BREAK:

672 emitIfBreak(MI);

673 break;

674

675 case AMDGPU::SI_LOOP:

676 emitLoop(MI);

677 break;

678

679 case AMDGPU::SI_WATERFALL_LOOP:

680 MI.setDesc(TII->get(AMDGPU::S_CBRANCH_EXECNZ));

681 break;

682

683 case AMDGPU::SI_END_CF:

684 SplitBB = emitEndCf(MI);

685 break;

686

687 default:

688 assert(false && "Attempt to process unsupported instruction");

689 break;

690 }

691

694 Next = std::next(I);

695 MachineInstr &MaskMI = *I;

697 case AMDGPU::S_AND_B64:

698 case AMDGPU::S_OR_B64:

699 case AMDGPU::S_AND_B32:

700 case AMDGPU::S_OR_B32:

701

702 combineMasks(MaskMI);

703 break;

704 default:

706 break;

707 }

708 }

709

710 return SplitBB;

711}

712

713bool SILowerControlFlow::removeMBBifRedundant(MachineBasicBlock &MBB) {

715 if (I.isDebugInstr() && I.isUnconditionalBranch())

716 return false;

717 }

718

720

722 MachineBasicBlock *FallThrough = nullptr;

723

726

729 if (P->getFallThrough(false) == &MBB)

730 FallThrough = P;

732 DTUpdates.push_back({DomTreeT::Insert, P, Succ});

733 DTUpdates.push_back({DomTreeT::Delete, P, &MBB});

734 }

736 if (LIS) {

739 }

740 if (MDT)

742 if (PDT)

744

748

749

750 MachineInstr *BranchMI = BuildMI(*FallThrough, FallThrough->end(),

753 if (LIS)

755 }

756

757 return true;

758}

759

760bool SILowerControlFlow::run(MachineFunction &MF) {

761 const GCNSubtarget &ST = MF.getSubtarget();

762 TII = ST.getInstrInfo();

766

768 BoolRC = TRI->getBoolRC();

769

770

771 const bool CanDemote =

773 for (auto &MBB : MF) {

774 bool IsKillBlock = false;

776 if (TII->isKillTerminator(Term.getOpcode())) {

778 IsKillBlock = true;

779 break;

780 }

781 }

782 if (CanDemote && !IsKillBlock) {

783 for (auto &MI : MBB) {

784 if (MI.getOpcode() == AMDGPU::SI_DEMOTE_I1) {

786 break;

787 }

788 }

789 }

790 }

791

795 BI != MF.end(); BI = NextBB) {

796 NextBB = std::next(BI);

797 MachineBasicBlock *MBB = &*BI;

798

802 Next = std::next(I);

803 MachineInstr &MI = *I;

804 MachineBasicBlock *SplitMBB = MBB;

805

806 switch (MI.getOpcode()) {

807 case AMDGPU::SI_IF:

808 case AMDGPU::SI_ELSE:

809 case AMDGPU::SI_IF_BREAK:

810 case AMDGPU::SI_WATERFALL_LOOP:

811 case AMDGPU::SI_LOOP:

812 case AMDGPU::SI_END_CF:

813 SplitMBB = process(MI);

815 break;

816 }

817

818 if (SplitMBB != MBB) {

821 }

822 }

823 }

824

825 optimizeEndCf();

826

828

834 }

835 }

836

837 RecomputeRegs.clear();

838 LoweredEndCf.clear();

839 LoweredIf.clear();

840 KillBlocks.clear();

841

843}

844

845bool SILowerControlFlowLegacy::runOnMachineFunction(MachineFunction &MF) {

846 const GCNSubtarget *ST = &MF.getSubtarget();

847

848 auto *LISWrapper = getAnalysisIfAvailable();

849 LiveIntervals *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;

850

851 auto *LVWrapper = getAnalysisIfAvailable();

852 LiveVariables *LV = LVWrapper ? &LVWrapper->getLV() : nullptr;

853 auto *MDTWrapper = getAnalysisIfAvailable();

854 MachineDominatorTree *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;

855 auto *PDTWrapper =

856 getAnalysisIfAvailable();

857 MachinePostDominatorTree *PDT =

858 PDTWrapper ? &PDTWrapper->getPostDomTree() : nullptr;

859 return SILowerControlFlow(ST, LIS, LV, MDT, PDT).run(MF);

860}

861

862PreservedAnalyses

872

873 bool Changed = SILowerControlFlow(ST, LIS, LV, MDT, PDT).run(MF);

876

883 return PA;

884}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder & UseMI

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

const TargetInstrInfo & TII

Provides AMDGPU specific target descriptions.

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

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

AMD GCN specific subclass of TargetSubtarget.

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

Register const TargetRegisterInfo * TRI

Promote Memory to Register

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

const SmallVectorImpl< MachineOperand > & Cond

static cl::opt< bool > RemoveRedundantEndcf("amdgpu-remove-redundant-endcf", cl::init(true), cl::ReallyHidden)

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

bool IsDead

Definition SILowerControlFlow.cpp:174

static bool isSimpleIf(const MachineInstr &MI, const MachineRegisterInfo *MRI)

Definition SILowerControlFlow.cpp:202

This file defines the SmallSet class.

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

const unsigned XorTermOpc

const unsigned MovTermOpc

const unsigned OrSaveExecOpc

const unsigned AndN2TermOpc

PassT::Result * getCachedResult(IRUnitT &IR) const

Get the cached result of an analysis pass for a given IR unit.

AnalysisUsage & addUsedIfAvailable()

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

AnalysisUsage & addPreserved()

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

Implements a dense probed hash-table based set.

void applyUpdates(ArrayRef< UpdateType > Updates)

Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...

CallingConv::ID getCallingConv() const

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

void removeAllRegUnitsForPhysReg(MCRegister Reg)

Remove associated live ranges for the register units associated with Reg.

SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)

LLVM_ABI void handleMove(MachineInstr &MI, bool UpdateFlags=false)

Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.

void RemoveMachineInstrFromMaps(MachineInstr &MI)

void removeInterval(Register Reg)

Interval removal.

LiveInterval & createAndComputeVirtRegInterval(Register Reg)

SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)

LLVM_ABI void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)

replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.

LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)

Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...

LLVM_ABI VarInfo & getVarInfo(Register Reg)

getVarInfo - Return the VarInfo structure for the specified VIRTUAL register.

const MCInstrDesc & get(unsigned Opcode) const

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

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

succ_iterator succ_begin()

unsigned succ_size() const

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

Remove successor from the successors list of this MachineBasicBlock.

pred_iterator pred_begin()

LLVM_ABI void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)

Given a machine basic block that branched to 'Old', change the code and CFG so that it branches to 'N...

LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const

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

LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)

Split a basic block into 2 pieces at SplitPoint.

LLVM_ABI void eraseFromParent()

This method unlinks 'this' from the containing function and deletes it.

iterator_range< iterator > terminators()

LLVM_ABI DebugLoc findBranchDebugLoc()

Find and return the merged DebugLoc of the branch instructions of the block.

iterator_range< succ_iterator > successors()

iterator_range< pred_iterator > predecessors()

MachineInstrBundleIterator< MachineInstr > iterator

Analysis pass which computes a MachineDominatorTree.

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

BasicBlockListType::iterator iterator

const TargetMachine & getTarget() const

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

const MachineInstrBuilder & add(const MachineOperand &MO) const

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

Add a new virtual register operand.

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

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

MachineOperand class - Representation of each machine instruction operand.

void setIsDead(bool Val=true)

Register getReg() const

getReg - Returns the register number.

MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...

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

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

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

static bool isVALU(const MachineInstr &MI)

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

Definition SILowerControlFlow.cpp:863

A vector that has set insertion semantics.

size_type count(const_arg_type key) const

Count the number of elements of a given key in the SetVector.

void clear()

Completely clear the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

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

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

bool contains(ConstPtrType Ptr) const

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

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

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

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

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

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

void push_back(const T &Elt)

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

const TargetRegisterInfo & getRegisterInfo() const

CodeGenOptLevel getOptLevel() const

Returns the optimization level: None, Less, Default, or Aggressive.

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.

self_iterator getIterator()

@ Kill

The last use of a register.

initializer< Ty > init(const Ty &Val)

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

NodeAddr< DefNode * > Def

This is an optimization pass for GlobalISel generic memory operations.

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

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

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()

Returns the minimum set of Analyses that all machine function passes must preserve.

auto reverse(ContainerTy &&C)

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

DominatorTreeBase< T, false > DomTreeBase

LLVM_ABI raw_ostream & dbgs()

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

class LLVM_GSL_OWNER SmallVector

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

char & SILowerControlFlowLegacyID

Definition SILowerControlFlow.cpp:181

@ Or

Bitwise or logical OR of integers.

@ Xor

Bitwise or logical XOR of integers.

@ And

Bitwise or logical AND of integers.

FunctionAddr VTableAddr Next

DWARFExpression::Operation Op

std::vector< MachineInstr * > Kills

Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...