LLVM: include/llvm/Support/GenericLoopInfoImpl.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14#ifndef LLVM_SUPPORT_GENERICLOOPINFOIMPL_H

15#define LLVM_SUPPORT_GENERICLOOPINFOIMPL_H

16

22

23namespace llvm {

24

25

26

27

28

29

30

31

32template <class BlockT, class LoopT>

36 for (const auto BB : blocks())

39

41 break;

42 }

43}

44

45

46

47template <class BlockT, class LoopT>

50 auto notInLoop = [&](BlockT *BB) { return contains(BB); };

51 auto isExitBlock = [&](BlockT *BB, bool AllowRepeats) -> BlockT * {

52 assert(!AllowRepeats && "Unexpected parameter value.");

53

55 };

56

58}

59

60

61

62

63template <class BlockT, class LoopT>

67 for (const auto BB : blocks())

70

72}

73

74

75

76template <class BlockT, class LoopT>

78 bool Unique) {

79 assert(!L->isInvalid() && "Loop not in a valid state!");

80 auto notInLoop = [&](BlockT *BB,

81 bool AllowRepeats) -> std::pair<BlockT *, bool> {

82 assert(AllowRepeats == Unique && "Unexpected parameter value.");

83 return {!L->contains(BB) ? BB : nullptr, false};

84 };

85 auto singleExitBlock = [&](BlockT *BB,

86 bool AllowRepeats) -> std::pair<BlockT *, bool> {

87 assert(AllowRepeats == Unique && "Unexpected parameter value.");

89 AllowRepeats);

90 };

92}

93

94template <class BlockT, class LoopT>

97 if (RC.second)

98

99 return false;

100

101 return !RC.first;

102}

103

104

105

106template <class BlockT, class LoopT>

110

111template <class BlockT, class LoopT>

113

114

117 for (BlockT *EB : UniqueExitBlocks)

120 return false;

121

122 return true;

123}

124

125

126

127template <class BlockT, class LoopT, typename PredicateT>

131 assert(!L->isInvalid() && "Loop not in a valid state!");

134 for (BlockT *BB : Filtered)

139}

140

141template <class BlockT, class LoopT>

145 [](const BlockT *BB) { return true; });

146}

147

148template <class BlockT, class LoopT>

152 assert(Latch && "Latch block must exists");

154 [Latch](const BlockT *BB) { return BB != Latch; });

155}

156

157template <class BlockT, class LoopT>

161

162template <class BlockT, class LoopT>

165 assert(Latch && "Latch block must exists");

166 auto IsExitBlock = [this](BlockT *BB, bool AllowRepeats) -> BlockT * {

167 assert(!AllowRepeats && "Unexpected parameter value.");

168 return contains(BB) ? BB : nullptr;

169 };

171}

172

173

174template <class BlockT, class LoopT>

178 for (const auto BB : blocks())

181

183}

184

186template

188

189template

191

192

193

196 return Block->isLegalToHoistInto();

197 return false;

198}

199}

200

201

202

203

204

205

206

207

208

209template <class BlockT, class LoopT>

212

214 if (!Out)

215 return nullptr;

216

217

219 return nullptr;

220

221

223 return nullptr;

224

225

226 return Out;

227}

228

229

230

231

232

233

234template <class BlockT, class LoopT>

237

238 BlockT *Out = nullptr;

239

240

243 if (contains(Pred)) {

244 if (Out && Out != Pred)

245 return nullptr;

246 Out = Pred;

247 }

248 }

249

250 return Out;

251}

252

253

254

255template <class BlockT, class LoopT>

259 BlockT *Latch = nullptr;

262 if (Latch)

263 return nullptr;

264 Latch = Pred;

266 }

267

268 return Latch;

270

271

272

274

275

276

277

278

279

280

281template <class BlockT, class LoopT>

285#ifndef NDEBUG

286 if (!Blocks.empty()) {

287 auto SameHeader = LIB[getHeader()];

289 "Incorrect LI specified for this loop!");

290 }

292 assert(NewBB && "Cannot add a null basic block to the loop!");

293 assert(!LIB[NewBB] && "BasicBlock already in the loop!");

294

295 LoopT *L = static_cast<LoopT *>(this);

296

297

298 LIB.BBMap[NewBB] = L;

300

301 while (L) {

302 L->addBlockEntry(NewBB);

303 L = L->getParentLoop();

304 }

305}

306

307

308

309

310

311template <class BlockT, class LoopT>

313 LoopT *NewChild) {

315 assert(OldChild->ParentLoop == this && "This loop is already broken!");

316 assert(!NewChild->ParentLoop && "NewChild already has a parent!");

317 typename std::vector<LoopT *>::iterator I = find(SubLoops, OldChild);

318 assert(I != SubLoops.end() && "OldChild not in loop!");

319 *I = NewChild;

320 OldChild->ParentLoop = nullptr;

321 NewChild->ParentLoop = static_cast<LoopT *>(this);

323

324

325template <class BlockT, class LoopT>

328#ifndef NDEBUG

329 assert(!Blocks.empty() && "Loop header is missing");

330

331

336

337

339

340

343 [&](BlockT *B) { return contains(B); }) &&

344 "Loop block has no in-loop successors!");

345

347 [&](BlockT *B) { return contains(B); }) &&

348 "Loop block has no in-loop predecessors!");

349

354

356 assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");

357 } else if (!OutsideLoopPreds.empty()) {

358

359

360

361 BlockT *EntryBB = &BB->getParent()->front();

363 for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)

364 assert(CB != OutsideLoopPreds[i] &&

365 "Loop has multiple entry points!");

366 }

368 "Loop contains function entry block!");

369

370 VisitedBBs.insert(BB);

371 }

372

374 dbgs() << "The following blocks are unreachable in the loop: ";

375 for (auto *BB : Blocks) {

376 if (!VisitedBBs.count(BB)) {

377 dbgs() << *BB << "\n";

378 }

379 }

380 assert(false && "Unreachable block in loop");

382

383

384 for (iterator I = begin(), E = end(); I != E; ++I)

385

386 for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();

387 BI != BE; ++BI) {

389 "Loop does not contain all the blocks of a subloop!");

390 }

391

392

393 if (ParentLoop) {

395 "Loop is not a subloop of its parent!");

396 }

397#endif

398}

399

400

401template <class BlockT, class LoopT>

405 Loops->insert(static_cast<const LoopT *>(this));

406

408

410 (*I)->verifyLoopNest(Loops);

411}

412

413template <class BlockT, class LoopT>

415 bool PrintNested, unsigned Depth) const {

418 OS << "Parallel ";

419 OS << "Loop at depth " << getLoopDepth() << " containing: ";

420

422 for (unsigned i = 0; i < getBlocks().size(); ++i) {

425 if (i)

426 OS << ",";

427 BB->printAsOperand(OS, false);

428 } else {

429 OS << '\n';

430 }

431

432 if (BB == H)

433 OS << "

";

435 OS << "";

437 OS << "";

439 BB->print(OS);

440 }

441

442 if (PrintNested) {

443 OS << "\n";

444

446 (*I)->print(OS, false, PrintNested, Depth + 2);

447 }

448}

449

450

451

452

453

454

455

456

457

458template <class BlockT, class LoopT>

463

464 unsigned NumBlocks = 0;

465 unsigned NumSubloops = 0;

467

468 std::vector<BlockT *> ReverseCFGWorklist(Backedges.begin(), Backedges.end());

469 while (!ReverseCFGWorklist.empty()) {

470 BlockT *PredBB = ReverseCFGWorklist.back();

471 ReverseCFGWorklist.pop_back();

472

473 LoopT *Subloop = LI->getLoopFor(PredBB);

474 if (!Subloop) {

476 continue;

477

478

480 ++NumBlocks;

481 if (PredBB == L->getHeader())

482 continue;

483

484 ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),

485 InvBlockTraits::child_begin(PredBB),

486 InvBlockTraits::child_end(PredBB));

487 } else {

488

489 Subloop = Subloop->getOutermostLoop();

490

491

492 if (Subloop == L)

493 continue;

494

495

496 Subloop->setParentLoop(L);

497 ++NumSubloops;

498 NumBlocks += Subloop->getBlocksVector().capacity();

499 PredBB = Subloop->getHeader();

500

501

502

503

506 ReverseCFGWorklist.push_back(Pred);

507 }

508 }

509 }

510 L->getSubLoopsVector().reserve(NumSubloops);

511 L->reserveBlocks(NumBlocks);

512}

513

514

517 using SuccIterTy = typename BlockTraits::ChildIteratorType;

518

520

521public:

523

524 void traverse(BlockT *EntryBlock);

525

526protected:

528};

529

530

531template <class BlockT, class LoopT>

533 for (BlockT *BB : post_order(EntryBlock))

535}

536

537

538

539

540template <class BlockT, class LoopT>

542 LoopT *Subloop = LI->getLoopFor(Block);

543 if (Subloop && Block == Subloop->getHeader()) {

544

545

546 if (!Subloop->isOutermost())

547 Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);

548 else

549 LI->addTopLevelLoop(Subloop);

550

551

552

553 Subloop->reverseBlock(1);

554 std::reverse(Subloop->getSubLoopsVector().begin(),

555 Subloop->getSubLoopsVector().end());

556

557 Subloop = Subloop->getParentLoop();

558 }

559 for (; Subloop; Subloop = Subloop->getParentLoop())

560 Subloop->addBlockEntry(Block);

561}

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577template <class BlockT, class LoopT>

579

581 for (auto DomNode : post_order(DomRoot)) {

582

583 BlockT *Header = DomNode->getBlock();

585

586

588

590 if (BackedgeNode && DomTree.dominates(DomNode, BackedgeNode))

593

594 if (!Backedges.empty()) {

595 LoopT *L = AllocateLoop(Header);

597 }

598 }

599

600

603}

604

605template <class BlockT, class LoopT>

609

610

611

612

613

614 for (LoopT *RootL : reverse(*this)) {

615 auto PreOrderLoopsInRootL = RootL->getLoopsInPreorder();

616 PreOrderLoops.append(PreOrderLoopsInRootL.begin(),

617 PreOrderLoopsInRootL.end());

618 }

619

620 return PreOrderLoops;

621}

623template <class BlockT, class LoopT>

627

628

629

630

631

632 for (LoopT *RootL : *this) {

634 "Must start with an empty preorder walk worklist.");

635 PreOrderWorklist.push_back(RootL);

636 do {

638

639

640 PreOrderWorklist.append(L->begin(), L->end());

642 } while (!PreOrderWorklist.empty());

643 }

644

645 return PreOrderLoops;

646}

647

648template <class BlockT, class LoopT>

650 LoopT *B) const {

651 if (A || B)

652 return nullptr;

653

654

655

656 while (A->getLoopDepth() > B->getLoopDepth())

657 A = A->getParentLoop();

658 while (B->getLoopDepth() > A->getLoopDepth())

659 B = B->getParentLoop();

660

661

662

663

664 while (A != B) {

665 A = A->getParentLoop();

666 B = B->getParentLoop();

667 }

668

669 return A;

670}

671

672template <class BlockT, class LoopT>

674 BlockT *B) const {

676}

677

678

679template <class BlockT, class LoopT>

681 for (unsigned i = 0; i < TopLevelLoops.size(); ++i)

682 TopLevelLoops[i]->print(OS);

683#if 0

685 E = BBMap.end(); I != E; ++I)

686 OS << "BB '" << I->first->getName() << "' level = "

687 << I->second->getLoopDepth() << "\n";

688#endif

689}

690

691template

695 return BB1 == BB2;

696}

697

698template <class BlockT, class LoopT>

701 const LoopT &L) {

702 LoopHeaders[L.getHeader()] = &L;

703 for (LoopT *SL : L)

705}

706

707#ifndef NDEBUG

708template <class BlockT, class LoopT>

709static void compareLoops(const LoopT *L, const LoopT *OtherL,

711 BlockT *H = L->getHeader();

712 BlockT *OtherH = OtherL->getHeader();

714 "Mismatched headers even though found in the same map entry!");

715

716 assert(L->getLoopDepth() == OtherL->getLoopDepth() &&

717 "Mismatched loop depth!");

718 const LoopT *ParentL = L, *OtherParentL = OtherL;

719 do {

720 assert(ParentL->getHeader() == OtherParentL->getHeader() &&

721 "Mismatched parent loop headers!");

722 ParentL = ParentL->getParentLoop();

723 OtherParentL = OtherParentL->getParentLoop();

724 } while (ParentL);

725

726 for (const LoopT *SubL : *L) {

727 BlockT *SubH = SubL->getHeader();

728 const LoopT *OtherSubL = OtherLoopHeaders.lookup(SubH);

729 assert(OtherSubL && "Inner loop is missing in computed loop info!");

730 OtherLoopHeaders.erase(SubH);

731 compareLoops(SubL, OtherSubL, OtherLoopHeaders);

732 }

733

734 std::vector<BlockT *> BBs = L->getBlocks();

735 std::vector<BlockT *> OtherBBs = OtherL->getBlocks();

737 "Mismatched basic blocks in the loops!");

738

741 OtherL->getBlocksSet();

744 "Mismatched basic blocks in BlocksSets!");

745}

746#endif

747

748template <class BlockT, class LoopT>

753 assert((*I)->isOutermost() && "Top-level loop has a parent!");

754 (*I)->verifyLoopNest(&Loops);

755 }

756

757

758#ifndef NDEBUG

759 for (auto &Entry : BBMap) {

760 const BlockT *BB = Entry.first;

761 LoopT *L = Entry.second;

762 assert(Loops.count(L) && "orphaned loop");

763 assert(L->contains(BB) && "orphaned block");

764 for (LoopT *ChildLoop : *L)

765 assert(!ChildLoop->contains(BB) &&

766 "BBMap should point to the innermost loop containing BB");

767 }

768

769

770 LoopInfoBase<BlockT, LoopT> OtherLI;

771 OtherLI.analyze(DomTree);

772

773

774

775

777 for (LoopT *L : OtherLI)

779

780

781

782

783 for (LoopT *L : *this) {

784 BlockT *Header = L->getHeader();

785 const LoopT *OtherL = OtherLoopHeaders.lookup(Header);

786 assert(OtherL && "Top level loop is missing in computed loop info!");

787

788 OtherLoopHeaders.erase(Header);

789

791 }

792

793

794

795 if (!OtherLoopHeaders.empty()) {

796 for (const auto &HeaderAndLoop : OtherLoopHeaders)

797 dbgs() << "Found new loop: " << *HeaderAndLoop.second << "\n";

798 llvm_unreachable("Found new loops when recomputing LoopInfo!");

799 }

800#endif

801}

802

803}

804

805#endif

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

static const Function * getParent(const Value *V)

bbsections Prepares for basic block by splitting functions into clusters of basic blocks

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

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

static bool isExitBlock(BasicBlock *BB, const SmallVectorImpl< BasicBlock * > &ExitBlocks)

Return true if the specified block is in the list.

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

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines generic set operations that may be used on set's of different types,...

SmallPtrSet< BasicBlock *, 8 > BlocksSet

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

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

bool erase(const KeyT &Val)

DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator

Implements a dense probed hash-table based set.

Base class for the actual dominator tree node.

DomTreeNodeBase< NodeT > * getRootNode()

getRootNode - This returns the entry node for the CFG of the function.

bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const

dominates - Returns true iff A dominates B.

bool isReachableFromEntry(const NodeT *A) const

isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...

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

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

Instances of this class are used to represent loops that are detected in the flow graph.

bool isAnnotatedParallel() const

Returns true if the loop is annotated parallel.

typename std::vector< LoopT * >::const_iterator iterator

BlockT * getLoopLatch() const

If there is a single latch block for this loop, return it.

Definition GenericLoopInfoImpl.h:256

void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const

Return all of the successor blocks of this loop.

Definition GenericLoopInfoImpl.h:64

unsigned getNumBlocks() const

void verifyLoop() const

Verify loop structure.

Definition GenericLoopInfoImpl.h:326

void verifyLoopNest(DenseSet< const LoopT * > *Loops) const

Verify loop structure of this loop and all nested loops.

Definition GenericLoopInfoImpl.h:402

BlockT * getUniqueLatchExitBlock() const

Return the unique exit block for the latch, or null if there are multiple different exit blocks or th...

Definition GenericLoopInfoImpl.h:163

void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const

Return all blocks inside the loop that have successors outside of the loop.

Definition GenericLoopInfoImpl.h:33

BlockT * getHeader() const

unsigned getLoopDepth() const

Return the nesting level of this loop.

void print(raw_ostream &OS, bool Verbose=false, bool PrintNested=true, unsigned Depth=0) const

Print loop with all the BBs inside it.

Definition GenericLoopInfoImpl.h:414

void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)

This method is used by other analyses to update loop information.

Definition GenericLoopInfoImpl.h:282

bool isInvalid() const

Return true if this loop is no longer valid.

BlockT * getLoopPredecessor() const

If the given loop's header has exactly one unique predecessor outside the loop, return it.

Definition GenericLoopInfoImpl.h:235

bool isLoopLatch(const BlockT *BB) const

void getExitEdges(SmallVectorImpl< Edge > &ExitEdges) const

Return all pairs of (inside_block,outside_block).

Definition GenericLoopInfoImpl.h:175

BlockT * getExitBlock() const

If getExitBlocks would return exactly one block, return that block.

Definition GenericLoopInfoImpl.h:107

bool hasNoExitBlocks() const

Return true if this loop does not have any exit blocks.

Definition GenericLoopInfoImpl.h:95

void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild)

This is used when splitting loops up.

Definition GenericLoopInfoImpl.h:312

BlockT * getLoopPreheader() const

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

Definition GenericLoopInfoImpl.h:210

ArrayRef< BlockT * > getBlocks() const

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

BlockT * getExitingBlock() const

If getExitingBlocks would return exactly one block, return that block.

Definition GenericLoopInfoImpl.h:48

void getUniqueExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const

Return all unique successor blocks of this loop.

Definition GenericLoopInfoImpl.h:142

bool hasDedicatedExits() const

Return true if no exit block for the loop has a predecessor that is outside the loop.

Definition GenericLoopInfoImpl.h:112

void getUniqueNonLatchExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const

Return all unique successor blocks of this loop except successors from Latch block are not considered...

Definition GenericLoopInfoImpl.h:149

bool isLoopExiting(const BlockT *BB) const

True if terminator in the block can branch to another block that is outside of the current loop.

BlockT * getUniqueExitBlock() const

If getUniqueExitBlocks would return exactly one block, return that block.

Definition GenericLoopInfoImpl.h:158

This class builds and contains all of the top-level loop structures in the specified function.

void verify(const DominatorTreeBase< BlockT, false > &DomTree) const

Definition GenericLoopInfoImpl.h:749

void analyze(const DominatorTreeBase< BlockT, false > &DomTree)

Create the loop forest using a stable algorithm.

Definition GenericLoopInfoImpl.h:578

SmallVector< LoopT *, 4 > getLoopsInReverseSiblingPreorder() const

Return all of the loops in the function in preorder across the loop nests, with siblings in reverse p...

Definition GenericLoopInfoImpl.h:625

void print(raw_ostream &OS) const

Definition GenericLoopInfoImpl.h:680

SmallVector< LoopT *, 4 > getLoopsInPreorder() const

Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...

Definition GenericLoopInfoImpl.h:607

LoopT * getSmallestCommonLoop(LoopT *A, LoopT *B) const

Find the innermost loop containing both given loops.

Definition GenericLoopInfoImpl.h:649

void changeLoopFor(BlockT *BB, LoopT *L)

Change the top-level loop that contains BB to the specified loop.

typename std::vector< LoopT * >::const_iterator iterator

iterator/begin/end - The interface to the top-level loops in the current function.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

Populate all loop data in a stable order during a single forward DFS.

Definition GenericLoopInfoImpl.h:515

void traverse(BlockT *EntryBlock)

Top-level driver for the forward DFS within the loop.

Definition GenericLoopInfoImpl.h:532

PopulateLoopsDFS(LoopInfoBase< BlockT, LoopT > *li)

Definition GenericLoopInfoImpl.h:522

void insertIntoLoop(BlockT *Block)

Add a single Block to its ancestor loops in PostOrder.

Definition GenericLoopInfoImpl.h:541

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.

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

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

reference emplace_back(ArgTypes &&... Args)

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.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

#define llvm_unreachable(msg)

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

decltype(&BlockT::isLegalToHoistInto) has_hoist_check

Definition GenericLoopInfoImpl.h:187

llvm::is_detected< has_hoist_check, BlockT > detect_has_hoist_check

Definition GenericLoopInfoImpl.h:190

bool isLegalToHoistInto(BlockT *Block)

SFINAE functions that dispatch to the isLegalToHoistInto member function or return false,...

Definition GenericLoopInfoImpl.h:194

This is an optimization pass for GlobalISel generic memory operations.

iterator_range< df_ext_iterator< T, SetTy > > depth_first_ext(const T &G, SetTy &S)

auto find(R &&Range, const T &Val)

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

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)

static void compareLoops(const LoopT *L, const LoopT *OtherL, DenseMap< BlockT *, const LoopT * > &OtherLoopHeaders)

Definition GenericLoopInfoImpl.h:709

bool set_is_subset(const S1Ty &S1, const S2Ty &S2)

set_is_subset(A, B) - Return true iff A in B

iterator_range< po_iterator< T > > post_order(const T &G)

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)

void sort(IteratorTy Start, IteratorTy End)

DominatorTreeBase< T, false > DomTreeBase

LLVM_ABI raw_ostream & dbgs()

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

bool hasSingleElement(ContainerTy &&C)

Returns true if the given container only contains a single element.

iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)

Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...

std::pair< BlockT *, bool > getExitBlockHelper(const LoopBase< BlockT, LoopT > *L, bool Unique)

getExitBlock - If getExitBlocks would return exactly one block, return that block.

Definition GenericLoopInfoImpl.h:77

std::pair< T *, bool > find_singleton_nested(R &&Range, Predicate P, bool AllowRepeats=false)

Return a pair consisting of the single value in Range that satisfies P( ,...

T * find_singleton(R &&Range, Predicate P, bool AllowRepeats=false)

Return the single value in Range that satisfies P( *, AllowRepeats)->T * returning n...

iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)

void addInnerLoopsToHeadersMap(DenseMap< BlockT *, const LoopT * > &LoopHeaders, const LoopInfoBase< BlockT, LoopT > &LI, const LoopT &L)

Definition GenericLoopInfoImpl.h:699

void getUniqueExitBlocksHelper(const LoopT *L, SmallVectorImpl< BlockT * > &ExitBlocks, PredicateT Pred)

Definition GenericLoopInfoImpl.h:128

typename detail::detector< void, Op, Args... >::value_t is_detected

Detects if a given trait holds for some set of arguments 'Args'.

iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)

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

Returns true if Element is found in Range.

bool compareVectors(std::vector< T > &BB1, std::vector< T > &BB2)

Definition GenericLoopInfoImpl.h:692

iterator_range< df_iterator< T > > depth_first(const T &G)

static void discoverAndMapSubloop(LoopT *L, ArrayRef< BlockT * > Backedges, LoopInfoBase< BlockT, LoopT > *LI, const DomTreeBase< BlockT > &DomTree)

Stable LoopInfo Analysis - Build a loop tree using stable iterators so the result does / not depend o...

Definition GenericLoopInfoImpl.h:459

std::pair< iterator, bool > insert(NodeRef N)