LLVM: lib/Analysis/MustExecute.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

24

25using namespace llvm;

26

27#define DEBUG_TYPE "must-execute"

28

31 return BlockColors;

32}

33

35 ColorVector &ColorsForNewBlock = BlockColors[New];

36 ColorVector &ColorsForOldBlock = BlockColors[Old];

37 ColorsForNewBlock = ColorsForOldBlock;

38}

39

44

48

50 assert(CurLoop != nullptr && "CurLoop can't be null");

52

54 MayThrow = HeaderMayThrow;

55

56

57

59 "First block must be header");

62 if (MayThrow)

63 break;

64 }

65

67}

68

70 return ICF.hasICF(BB);

71}

72

76

78 assert(CurLoop != nullptr && "CurLoop can't be null");

79 ICF.clear();

80 MW.clear();

81 MayThrow = false;

82

83 for (const auto &BB : CurLoop->blocks())

84 if (ICF.hasICF(&*BB)) {

85 MayThrow = true;

86 break;

87 }

89}

90

93 ICF.insertInstructionTo(Inst, BB);

94 MW.insertInstructionTo(Inst, BB);

95}

96

98 ICF.removeInstruction(Inst);

99 MW.removeInstruction(Inst);

100}

101

111

112

113

114

117 const Loop *CurLoop) {

119 if (!CondExitBlock)

120

121 return false;

122 assert(CurLoop->contains(CondExitBlock) && "meaning of exit block");

124 if (!BI || !BI->isConditional())

125 return false;

126

127

129 return BI->getSuccessor(Cond->getZExtValue() ? 1 : 0) == ExitBlock;

132 return false;

133

134

135

138 auto *RHS = Cond->getOperand(1);

140 Pred = Cond->getSwappedPredicate();

142 RHS = Cond->getOperand(0);

144 return false;

145 }

146

148 auto *IVStart = LHS->getIncomingValueForBlock(CurLoop->getLoopPreheader());

150 Pred, IVStart, RHS, {DL, nullptr, DT, nullptr, BI});

152 if (!SimpleCst)

153 return false;

154 if (ExitBlock == BI->getSuccessor(0))

155 return SimpleCst->isZeroValue();

156 assert(ExitBlock == BI->getSuccessor(1) && "implied by above");

157 return SimpleCst->isAllOnesValue();

158}

159

160

161

162

163

164

165

169 assert(Predecessors.empty() && "Garbage in predecessors set?");

170 assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");

172 return;

175 if (!CurLoop->contains(Pred))

176 continue;

177 Predecessors.insert(Pred);

179 }

180 while (!WorkList.empty()) {

182 assert(CurLoop->contains(Pred) && "Should only reach loop blocks!");

183

184 if (Pred == CurLoop->getHeader())

185 continue;

186

187

188

189

190

191

192 for (const auto *PredPred : predecessors(Pred))

193 if (CurLoop->contains(PredPred) && Predecessors.insert(PredPred).second)

195 }

196}

197

201 assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");

202

203

205 return true;

206

207

208

211

212

213

214

216

217

218 if (Predecessors.contains(Pred))

219 return false;

220

221

222

223

224

225

226

228 for (const auto *Pred : Predecessors) {

229

231 return false;

232

233

234

236 continue;

237

238 for (const auto *Succ : successors(Pred))

239 if (CheckedSuccessors.insert(Succ).second &&

240 Succ != BB && !Predecessors.count(Succ))

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255 if (CurLoop->contains(Succ) ||

257 return false;

258 }

259

260

261 return true;

262}

263

264

265

268 const Loop *CurLoop) const {

269

270

271

273

274

275

276

277 return !HeaderMayThrow ||

278 &*Inst.getParent()->getFirstNonPHIOrDbg() == &Inst;

279

280

281

283}

284

287 const Loop *CurLoop) const {

288 return !ICF.isDominatedByICFIFromSameBlock(&Inst) &&

290}

291

293 const Loop *CurLoop) const {

294 assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");

295

296

298 return true;

299

300

301

304

305

306 for (const auto *Pred : Predecessors)

307 if (MW.mayWriteToMemory(Pred))

308 return false;

309 return true;

310}

311

313 const Loop *CurLoop) const {

314 auto *BB = I.getParent();

315 assert(CurLoop->contains(BB) && "Should only be called for loop blocks!");

316 return !MW.isDominatedByMemoryWriteFromSameBlock(&I) &&

318}

319

329

330namespace {

331

332

334 DenseMap<const Value*, SmallVector<Loop*, 4> > MustExec;

335

336public:

337 MustExecuteAnnotatedWriter(const Function &F,

338 DominatorTree &DT, LoopInfo &LI) {

341 while (L) {

343 MustExec[&I].push_back(L);

344 }

345 L = L->getParentLoop();

346 };

347 }

348 }

349 MustExecuteAnnotatedWriter(const Module &M,

350 DominatorTree &DT, LoopInfo &LI) {

351 for (const auto &F : M)

354 while (L) {

356 MustExec[&I].push_back(L);

357 }

358 L = L->getParentLoop();

359 };

360 }

361 }

362

363

364 void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {

365 if (!MustExec.count(&V))

366 return;

367

369 const auto NumLoops = Loops.size();

370 if (NumLoops > 1)

371 OS << " ; (mustexec in " << NumLoops << " loops: ";

372 else

373 OS << " ; (mustexec in: ";

374

375 ListSeparator LS;

376 for (const Loop *L : Loops)

377 OS << LS << L->getHeader()->getName();

378 OS << ")";

379 }

380};

381}

382

383

385 if (L.getHeader()->getParent()->hasFnAttribute(Attribute::WillReturn))

386 return false;

387

388

389 return true;

390}

391

393 if (!LI)

394 return false;

396 RPOTraversal FuncRPOT(&F);

398 const LoopInfo>(FuncRPOT, *LI);

399}

400

401

402

403template <typename K, typename V, typename FnTy, typename... ArgsTy>

405 FnTy &&Fn, ArgsTy &&...args) {

406 std::optional &OptVal = Map[Key];

407 if (!OptVal)

408 OptVal = Fn(std::forward(args)...);

409 return *OptVal;

410}

411

416

418 << (LI ? " [LI]" : "") << (PDT ? " [PDT]" : ""));

419

421 const Loop *L = LI ? LI->getLoopFor(InitBB) : nullptr;

422 const BasicBlock *HeaderBB = L ? L->getHeader() : InitBB;

423 bool WillReturnAndNoThrow = (F.hasFnAttribute(Attribute::WillReturn) ||

425 F.doesNotThrow();

427 << (WillReturnAndNoThrow ? " [WillReturn] [NoUnwind]" : "")

428 << "\n");

429

430

431

434 bool IsLatch = SuccBB == HeaderBB;

435

436

437 if (!WillReturnAndNoThrow || !IsLatch)

439 }

441

442

443 if (Worklist.empty())

444 return nullptr;

445

446

447 if (Worklist.size() == 1)

448 return Worklist[0];

449

450

451

452

454 if (PDT)

455 if (const auto *InitNode = PDT->getNode(InitBB))

456 if (const auto *IDomNode = InitNode->getIDom())

457 JoinBB = IDomNode->getBlock();

458

459 if (!JoinBB && Worklist.size() == 2) {

460 const BasicBlock *Succ0 = Worklist[0];

461 const BasicBlock *Succ1 = Worklist[1];

464 if (Succ0UniqueSucc == InitBB) {

465

466

467 JoinBB = Succ1;

468 } else if (Succ1UniqueSucc == InitBB) {

469

470

471 JoinBB = Succ0;

472 } else if (Succ0 == Succ1UniqueSucc) {

473

474

475 JoinBB = Succ0;

476 } else if (Succ1 == Succ0UniqueSucc) {

477

478

479 JoinBB = Succ1;

480 } else if (Succ0UniqueSucc == Succ1UniqueSucc) {

481

482

483 JoinBB = Succ0UniqueSucc;

484 }

485 }

486

487 if (!JoinBB && L)

488 JoinBB = L->getUniqueExitBlock();

489

490 if (!JoinBB)

491 return nullptr;

492

494

495

496

497

498

499

500

501

502

503 if (F.hasFnAttribute(Attribute::WillReturn) || F.doesNotThrow()) {

504

505 auto BlockTransfersExecutionToSuccessor = [](const BasicBlock *BB) {

507 };

508

510 while (!Worklist.empty()) {

512 if (ToBB == JoinBB)

513 continue;

514

515

516 if (!Visited.insert(ToBB).second) {

517 if (F.hasFnAttribute(Attribute::WillReturn)) {

518 if (!LI)

519 return nullptr;

520

523 if (MayContainIrreducibleControl)

524 return nullptr;

525

528 return nullptr;

529 }

530

531 continue;

532 }

533

534

535

537 ToBB, BlockTransferMap, BlockTransfersExecutionToSuccessor, ToBB);

538 if (!TransfersExecution)

539 return nullptr;

540

542 }

543 }

544

546 return JoinBB;

547}

553 << (LI ? " [LI]" : "") << (DT ? " [DT]" : ""));

554

555

556

557

558 if (DT)

559 if (const auto *InitNode = DT->getNode(InitBB))

560 if (const auto *IDomNode = InitNode->getIDom())

561 return IDomNode->getBlock();

562

563 const Loop *L = LI ? LI->getLoopFor(InitBB) : nullptr;

564 const BasicBlock *HeaderBB = L ? L->getHeader() : nullptr;

565

566

569 bool IsBackedge =

570 (PredBB == InitBB) || (HeaderBB == InitBB && L->contains(PredBB));

571

572

573 if (!IsBackedge)

575 }

576

577

578 if (Worklist.empty())

579 return nullptr;

580

581

582 if (Worklist.size() == 1)

583 return Worklist[0];

584

586 if (Worklist.size() == 2) {

587 const BasicBlock *Pred0 = Worklist[0];

588 const BasicBlock *Pred1 = Worklist[1];

591 if (Pred0 == Pred1UniquePred) {

592

593

594 JoinBB = Pred0;

595 } else if (Pred1 == Pred0UniquePred) {

596

597

598 JoinBB = Pred1;

599 } else if (Pred0UniquePred == Pred1UniquePred) {

600

601

602 JoinBB = Pred0UniquePred;

603 }

604 }

605

606 if (!JoinBB && L)

607 JoinBB = L->getHeader();

608

609

610

611

612 return JoinBB;

613}

614

618 if (!PP)

619 return PP;

620 LLVM_DEBUG(dbgs() << "Find next instruction for " << *PP << "\n");

621

622

624 LLVM_DEBUG(dbgs() << "\tReached terminator in intra-block mode, done\n");

625 return nullptr;

626 }

627

628

629

630

632 if (!TransfersExecution)

633 return nullptr;

634

635

636

637

638

641 LLVM_DEBUG(dbgs() << "\tIntermediate instruction does transfer control\n");

642 return NextPP;

643 }

644

645

647

648

651 return nullptr;

652 }

653

654

655

658 dbgs() << "\tUnconditional terminator, continue with successor\n");

660 }

661

662

663

664

666 return &JoinBB->front();

667

669 return nullptr;

670}

671

675 if (!PP)

676 return PP;

677

679 LLVM_DEBUG(dbgs() << "Find next instruction for " << *PP

680 << (IsFirst ? " [IsFirst]" : "") << "\n");

681

682

683

685 LLVM_DEBUG(dbgs() << "\tReached block front in intra-block mode, done\n");

686 return nullptr;

687 }

688

689

691

692

693

694 if (!IsFirst) {

697 dbgs() << "\tIntermediate instruction, continue with previous\n");

698

699 return PrevPP;

700 }

701

702

703

704

705

707 return &JoinBB->back();

708

710 return nullptr;

711}

712

715 : Explorer(Explorer), CurInst(I) {

716 reset(I);

717}

718

719void MustBeExecutedIterator::reset(const Instruction *I) {

720 Visited.clear();

721 resetInstruction(I);

722}

723

724void MustBeExecutedIterator::resetInstruction(const Instruction *I) {

725 CurInst = I;

726 Head = Tail = nullptr;

729 if (Explorer.ExploreCFGForward)

730 Head = I;

731 if (Explorer.ExploreCFGBackward)

732 Tail = I;

733}

734

735const Instruction *MustBeExecutedIterator::advance() {

736 assert(CurInst && "Cannot advance an end iterator!");

737 Head = Explorer.getMustBeExecutedNextInstruction(*this, Head);

738 if (Head && Visited.insert({Head, ExplorationDirection ::FORWARD}).second)

739 return Head;

740 Head = nullptr;

741

742 Tail = Explorer.getMustBeExecutedPrevInstruction(*this, Tail);

743 if (Tail && Visited.insert({Tail, ExplorationDirection ::BACKWARD}).second)

744 return Tail;

745 Tail = nullptr;

746 return nullptr;

747}

748

753

754 MustExecuteAnnotatedWriter Writer(F, DT, LI);

755 F.print(OS, &Writer);

757}

758

763 GetterTy LIGetter = [&](const Function &F) {

765 };

766 GetterTy DTGetter = [&](const Function &F) {

768 };

769 GetterTy PDTGetter = [&](const Function &F) {

771 };

772

774 true,

775 true,

776 true, LIGetter, DTGetter, PDTGetter);

777

780 OS << "-- Explore context of: " << I << "\n";

782 OS << " [F: " << CI->getFunction()->getName() << "] " << *CI << "\n";

783 }

784 }

786}

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Expand Atomic instructions

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

This header defines various interfaces for pass management in LLVM.

Machine Check Debug Module

static void collectTransitivePredecessors(const Loop *CurLoop, const BasicBlock *BB, SmallPtrSetImpl< const BasicBlock * > &Predecessors)

Collect all blocks from CurLoop which lie on all possible paths from the header of CurLoop (inclusive...

Definition MustExecute.cpp:166

static bool maybeEndlessLoop(const Loop &L)

Return true if L might be an endless loop.

Definition MustExecute.cpp:384

static V getOrCreateCachedOptional(K Key, DenseMap< K, std::optional< V > > &Map, FnTy &&Fn, ArgsTy &&...args)

Lookup Key in Map and return the result, potentially after initializing the optional through Fn(args)...

Definition MustExecute.cpp:404

static bool isMustExecuteIn(const Instruction &I, Loop *L, DominatorTree *DT)

Definition MustExecute.cpp:320

static bool CanProveNotTakenFirstIteration(const BasicBlock *ExitBlock, const DominatorTree *DT, const Loop *CurLoop)

Return true if we can prove that the given ExitBlock is not reached on the first iteration of the giv...

Definition MustExecute.cpp:115

Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...

FunctionAnalysisManager FAM

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

const SmallVectorImpl< MachineOperand > & Cond

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

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

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

LLVM_ABI const BasicBlock * getUniqueSuccessor() const

Return the successor of this block if it has a unique successor.

LLVM_ABI const BasicBlock * getSinglePredecessor() const

Return the predecessor of this block if it has a single predecessor block.

const Instruction & front() const

LLVM_ABI const BasicBlock * getUniquePredecessor() const

Return the predecessor of this block if it has a unique predecessor block.

LLVM_ABI const Module * getModule() const

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

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

This is an important base class in LLVM.

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

size_type count(const_arg_type_t< KeyT > Val) const

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

Analysis pass which computes a DominatorTree.

DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const

getNode - return the (Post)DominatorTree node for the specified basic block.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

bool hasPersonalityFn() const

Check whether this function has a personality function.

Constant * getPersonalityFn() const

Get the personality function associated with this function.

bool blockMayThrow(const BasicBlock *BB) const override

Returns true iff the block BB potentially may throw exception.

Definition MustExecute.cpp:69

bool doesNotWriteMemoryBefore(const BasicBlock *BB, const Loop *CurLoop) const

Returns true if we could not execute a memory-modifying instruction before we enter BB under assumpti...

Definition MustExecute.cpp:292

void removeInstruction(const Instruction *Inst)

Inform safety info that we are planning to remove the instruction Inst from its block.

Definition MustExecute.cpp:97

bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT, const Loop *CurLoop) const override

Returns true if the instruction in a loop is guaranteed to execute at least once (under the assumptio...

Definition MustExecute.cpp:285

bool anyBlockMayThrow() const override

Returns true iff any block of the loop for which this info is contains an instruction that may throw ...

Definition MustExecute.cpp:73

void computeLoopSafetyInfo(const Loop *CurLoop) override

Computes safety information for a loop checks loop body & header for the possibility of may throw exc...

Definition MustExecute.cpp:77

void insertInstructionTo(const Instruction *Inst, const BasicBlock *BB)

Inform the safety info that we are planning to insert a new instruction Inst into the basic block BB.

Definition MustExecute.cpp:91

LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY

Return the number of successors that this instruction has.

LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY

Return the specified successor. This instruction must be a terminator.

bool isTerminator() const

Analysis pass that exposes the LoopInfo for a function.

bool contains(const LoopT *L) const

Return true if the specified loop is contained within in this loop.

BlockT * getHeader() const

iterator_range< block_iterator > blocks() const

BlockT * getLoopPreheader() const

If there is a preheader for this loop, return it.

ArrayRef< BlockT * > getBlocks() const

Get a list of the basic blocks which make up this loop.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

LLVM_ABI bool allLoopPathsLeadToBlock(const Loop *CurLoop, const BasicBlock *BB, const DominatorTree *DT) const

Return true if we must reach the block BB under assumption that the loop CurLoop is entered.

Definition MustExecute.cpp:198

LLVM_ABI void copyColors(BasicBlock *New, BasicBlock *Old)

Copy colors of block Old into the block New.

Definition MustExecute.cpp:34

LLVM_ABI void computeBlockColors(const Loop *CurLoop)

Computes block colors.

Definition MustExecute.cpp:102

LLVM_ABI const DenseMap< BasicBlock *, ColorVector > & getBlockColors() const

Returns block colors map that is used to update funclet operand bundles.

Definition MustExecute.cpp:30

virtual bool blockMayThrow(const BasicBlock *BB) const =0

Returns true iff the block BB potentially may throw exception.

Represents a single loop in the control flow graph.

A Module instance is used to store all the information related to an LLVM module.

const DataLayout & getDataLayout() const

Get the data layout for the module's target platform.

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition MustExecute.cpp:760

LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

Definition MustExecute.cpp:749

Analysis pass which computes a PostDominatorTree.

PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Simple and conservative implementation of LoopSafetyInfo that can give false-positive answers to its ...

bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT, const Loop *CurLoop) const override

Returns true if the instruction in a loop is guaranteed to execute at least once.

Definition MustExecute.cpp:266

void computeLoopSafetyInfo(const Loop *CurLoop) override

Computes safety information for a loop checks loop body & header for the possibility of may throw exc...

Definition MustExecute.cpp:49

bool anyBlockMayThrow() const override

Returns true iff any block of the loop for which this info is contains an instruction that may throw ...

Definition MustExecute.cpp:45

bool blockMayThrow(const BasicBlock *BB) const override

Returns true iff the block BB potentially may throw exception.

Definition MustExecute.cpp:40

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

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.

bool contains(ConstPtrType Ptr) const

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

void push_back(const T &Elt)

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

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

const ParentTy * getParent() const

NodeTy * getNextNode()

Get the next node, or nullptr for the list tail.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto successors(const MachineBasicBlock *BB)

LLVM_ABI bool isGuaranteedToExecuteForEveryIteration(const Instruction *I, const Loop *L)

Return true if this function can prove that the instruction I is executed for every iteration of the ...

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

LLVM_ABI DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)

If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...

InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy

Provide the FunctionAnalysisManager to Module proxy.

bool isScopedEHPersonality(EHPersonality Pers)

Returns true if this personality uses scope-style EH IR instructions: catchswitch,...

auto dyn_cast_or_null(const Y &Val)

bool containsIrreducibleCFG(RPOTraversalT &RPOTraversal, const LoopInfoT &LI)

Return true if the control flow in RPOTraversal is irreducible.

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)

See if the given exception handling personality function is one that we understand.

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)

Return true if this function can prove that the instruction I will always transfer execution to one o...

TinyPtrVector< BasicBlock * > ColorVector

auto predecessors(const MachineBasicBlock *BB)

LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)

Given operands for a CmpInst, fold the result or return null.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)

Definition MustExecute.cpp:392

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

A "must be executed context" for a given program point PP is the set of instructions,...

const bool ExploreInterBlock

Parameter that limit the performed exploration.

LLVM_ABI const BasicBlock * findBackwardJoinPoint(const BasicBlock *InitBB)

Find the next join point from InitBB in backward direction.

Definition MustExecute.cpp:549

LLVM_ABI const Instruction * getMustBeExecutedNextInstruction(MustBeExecutedIterator &It, const Instruction *PP)

Return the next instruction that is guaranteed to be executed after PP.

Definition MustExecute.cpp:616

llvm::iterator_range< iterator > range(const Instruction *PP)

}

LLVM_ABI const Instruction * getMustBeExecutedPrevInstruction(MustBeExecutedIterator &It, const Instruction *PP)

Return the previous instr.

Definition MustExecute.cpp:673

LLVM_ABI const BasicBlock * findForwardJoinPoint(const BasicBlock *InitBB)

Find the next join point from InitBB in forward direction.

Definition MustExecute.cpp:413

Must be executed iterators visit stretches of instructions that are guaranteed to be executed togethe...

MustBeExecutedIterator(const MustBeExecutedIterator &Other)=default