LLVM: lib/Transforms/Scalar/GVNSink.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

69#include

70#include

71#include

72#include

73#include

74

75using namespace llvm;

77

78#define DEBUG_TYPE "gvn-sink"

79

80STATISTIC(NumRemoved, "Number of instructions removed");

81

86

92

93

94

95namespace {

96

97

98

99

100

101struct SinkingInstructionCandidate {

102 unsigned NumBlocks;

103 unsigned NumInstructions;

104 unsigned NumPHIs;

105 unsigned NumMemoryInsts;

106 int Cost = -1;

108

109 void calculateCost(unsigned NumOrigPHIs, unsigned NumOrigBlocks) {

110 unsigned NumExtraPHIs = NumPHIs - NumOrigPHIs;

111 unsigned SplitEdgeCost = (NumOrigBlocks > NumBlocks) ? 2 : 0;

112 Cost = (NumInstructions * (NumBlocks - 1)) -

113 (NumExtraPHIs *

114 NumExtraPHIs)

115 - SplitEdgeCost;

116 }

117

118 bool operator>(const SinkingInstructionCandidate &Other) const {

120 }

121};

122

123

124

125

126

127

128class ModelledPHI {

131

132public:

133 ModelledPHI() = default;

134

135 ModelledPHI(const PHINode *PN,

136 const DenseMap<const BasicBlock *, unsigned> &BlockOrder) {

137

138

139

140 using OpsType = std::pair<BasicBlock *, Value *>;

144

145 auto ComesBefore = [&](OpsType O1, OpsType O2) {

146 return BlockOrder.lookup(O1.first) < BlockOrder.lookup(O2.first);

147 };

148

150

151 for (auto &P : Ops) {

154 }

155 }

156

157

158

159

160 static ModelledPHI createDummy(size_t ID) {

161 ModelledPHI M;

162 M.Values.push_back(reinterpret_cast<Value*>(ID));

163 return M;

164 }

165

166 void

167 verifyModelledPHI(const DenseMap<const BasicBlock *, unsigned> &BlockOrder) {

169 "Modelling PHI with less than 2 values");

170 [[maybe_unused]] auto ComesBefore = [&](const BasicBlock *BB1,

172 return BlockOrder.lookup(BB1) < BlockOrder.lookup(BB2);

173 };

175 int C = 0;

176 for (const Value *V : Values) {

179 (void)C;

180 }

181 C++;

182 }

183 }

184

185 ModelledPHI(SmallVectorImpl<Instruction *> &V,

186 SmallSetVector<BasicBlock *, 4> &B,

187 const DenseMap<const BasicBlock *, unsigned> &BlockOrder) {

188

191 verifyModelledPHI(BlockOrder);

192 }

193

194

195

197 SmallSetVector<BasicBlock *, 4> &B) {

199 for (auto *I : Insts)

200 Values.push_back(I->getOperand(OpNum));

201 }

202

203

204

205 void restrictToBlocks(const SmallSetVector<BasicBlock *, 4> &NewBlocks) {

206 auto BI = Blocks.begin();

207 auto VI = Values.begin();

208 while (BI != Blocks.end()) {

209 assert(VI != Values.end());

210 if (!NewBlocks.contains(*BI)) {

211 BI = Blocks.erase(BI);

212 VI = Values.erase(VI);

213 } else {

214 ++BI;

215 ++VI;

216 }

217 }

219 }

220

222

223 bool areAllIncomingValuesSame() const {

225 }

226

227 bool areAllIncomingValuesSameType() const {

229 Values, [&](Value *V) { return V->getType() == Values[0]->getType(); });

230 }

231

232 bool areAnyIncomingValuesConstant() const {

234 }

235

236

237 unsigned hash() const {

238

240 }

241

243 return Values == Other.Values && Blocks == Other.Blocks;

244 }

245};

246}

247

248#ifndef NDEBUG

250 const SinkingInstructionCandidate &C) {

251 OS << "<Candidate Cost=" << C.Cost << " #Blocks=" << C.NumBlocks

252 << " #Insts=" << C.NumInstructions << " #PHIs=" << C.NumPHIs << ">";

253 return OS;

254}

255#endif

256

259 static ModelledPHI Dummy = ModelledPHI::createDummy(0);

260 return Dummy;

261 }

262

264 static ModelledPHI Dummy = ModelledPHI::createDummy(1);

265 return Dummy;

266 }

267

268 static unsigned getHashValue(const ModelledPHI &V) { return V.hash(); }

269

270 static bool isEqual(const ModelledPHI &LHS, const ModelledPHI &RHS) {

271 return LHS == RHS;

272 }

273};

274

276

277namespace {

278

279

280

281

282

283

284

285

286

287

288

289

290

291

293 unsigned MemoryUseOrder = -1;

294 bool Volatile = false;

296

297public:

301 allocateOperands(R, A);

302 setOpcode(I->getOpcode());

303 setType(I->getType());

304

306 ShuffleMask = SVI->getShuffleMask().copy(A);

307

308 for (auto &U : I->uses())

309 op_push_back(U.getUser());

311 }

312

313 void setMemoryUseOrder(unsigned MUO) { MemoryUseOrder = MUO; }

314 void setVolatile(bool V) { Volatile = V; }

315

316 hash_code getHashValue() const override {

318 Volatile, ShuffleMask);

319 }

320

321 template hash_code getHashValue(Function MapFn) {

323 ShuffleMask);

324 for (auto *V : operands())

326 return H;

327 }

328};

329

331

332class ValueTable {

338 uint32_t nextValueNumber = 1;

339 BasicBlocksSet ReachableBBs;

340

341

342

343

344 InstructionUseExpr *createExpr(Instruction *I) {

345 InstructionUseExpr *E =

348 E->setMemoryUseOrder(getMemoryUseOrder(I));

349

352 E->setOpcode((C->getOpcode() << 8) | Predicate);

353 }

354 return E;

355 }

356

357

358

359

360 template InstructionUseExpr *createMemoryExpr(Inst *I) {

362 return nullptr;

363 InstructionUseExpr *E = createExpr(I);

364 E->setVolatile(I->isVolatile());

365 return E;

366 }

367

368public:

370

371

372 void setReachableBBs(const BasicBlocksSet &ReachableBBs) {

373 this->ReachableBBs = ReachableBBs;

374 }

375

376

377

379 auto VI = ValueNumbering.find(V);

380 if (VI != ValueNumbering.end())

381 return VI->second;

382

384 ValueNumbering[V] = nextValueNumber;

385 return nextValueNumber++;

386 }

387

389 if (!ReachableBBs.contains(I->getParent()))

390 return ~0U;

391

392 InstructionUseExpr *exp = nullptr;

393 switch (I->getOpcode()) {

394 case Instruction::Load:

396 break;

397 case Instruction::Store:

399 break;

400 case Instruction::Call:

401 case Instruction::Invoke:

402 case Instruction::FNeg:

403 case Instruction::Add:

404 case Instruction::FAdd:

405 case Instruction::Sub:

406 case Instruction::FSub:

407 case Instruction::Mul:

408 case Instruction::FMul:

409 case Instruction::UDiv:

410 case Instruction::SDiv:

411 case Instruction::FDiv:

412 case Instruction::URem:

413 case Instruction::SRem:

414 case Instruction::FRem:

415 case Instruction::Shl:

416 case Instruction::LShr:

417 case Instruction::AShr:

418 case Instruction::And:

419 case Instruction::Or:

420 case Instruction::Xor:

421 case Instruction::ICmp:

422 case Instruction::FCmp:

423 case Instruction::Trunc:

424 case Instruction::ZExt:

425 case Instruction::SExt:

426 case Instruction::FPToUI:

427 case Instruction::FPToSI:

428 case Instruction::UIToFP:

429 case Instruction::SIToFP:

430 case Instruction::FPTrunc:

431 case Instruction::FPExt:

432 case Instruction::PtrToInt:

433 case Instruction::PtrToAddr:

434 case Instruction::IntToPtr:

435 case Instruction::BitCast:

436 case Instruction::AddrSpaceCast:

437 case Instruction::Select:

438 case Instruction::ExtractElement:

439 case Instruction::InsertElement:

440 case Instruction::ShuffleVector:

441 case Instruction::InsertValue:

442 case Instruction::GetElementPtr:

443 exp = createExpr(I);

444 break;

445 default:

446 break;

447 }

448

449 if (!exp) {

450 ValueNumbering[V] = nextValueNumber;

451 return nextValueNumber++;

452 }

453

454 uint32_t e = ExpressionNumbering[exp];

455 if (!e) {

456 hash_code H = exp->getHashValue([=](Value *V) { return lookupOrAdd(V); });

457 auto [I, Inserted] = HashNumbering.try_emplace(H, nextValueNumber);

458 e = I->second;

459 if (Inserted)

460 ExpressionNumbering[exp] = nextValueNumber++;

461 }

462 ValueNumbering[V] = e;

463 return e;

464 }

465

466

467

469 auto VI = ValueNumbering.find(V);

470 assert(VI != ValueNumbering.end() && "Value not numbered?");

471 return VI->second;

472 }

473

474

475 void clear() {

476 ValueNumbering.clear();

477 ExpressionNumbering.clear();

478 HashNumbering.clear();

480 nextValueNumber = 1;

481 }

482

483

484

485

486

487

488

489

490

491

492

495 for (auto I = std::next(Inst->getIterator()), E = BB->end();

496 I != E && I->isTerminator(); ++I) {

498 continue;

500 continue;

503 continue;

505 if (II && II->onlyReadsMemory())

506 continue;

507 return lookupOrAdd(&*I);

508 }

509 return 0;

510 }

511};

512

513

514

515class GVNSink {

516public:

517 GVNSink() = default;

518

520 LLVM_DEBUG(dbgs() << "GVNSink: running on function @" << F.getName()

521 << "\n");

522

523 unsigned NumSunk = 0;

526

527

528

529

530

531 unsigned NodeOrdering = 0;

532 RPOTOrder[*RPOT.begin()] = ++NodeOrdering;

533 for (auto *BB : RPOT)

535 RPOTOrder[BB] = ++NodeOrdering;

536 for (auto *N : RPOT)

537 NumSunk += sinkBB(N);

538

539 return NumSunk > 0;

540 }

541

542private:

543 ValueTable VN;

545

546 bool shouldAvoidSinkingInstruction(Instruction *I) {

547

549 I->getType()->isTokenTy())

550 return true;

551 return false;

552 }

553

554

555

556

557 std::optional

559 unsigned &InstNum, unsigned &MemoryInstNum,

562

563

567 auto MPHI = ModelledPHI(&PN, RPOTOrder);

570 }

571 }

572

573

574

576

577

578

580

581

582 void foldPointlessPHINodes(BasicBlock *BB) {

583 auto I = BB->begin();

586 return V == PN->getIncomingValue(0);

587 }))

588 continue;

591 else

594 }

595 }

596};

597}

598

599std::optional

600GVNSink::analyzeInstructionForSinking(LockstepReverseIterator &LRI,

601 unsigned &InstNum,

602 unsigned &MemoryInstNum,

604 SmallPtrSetImpl<Value *> &PHIContents) {

605 auto Insts = *LRI;

606 LLVM_DEBUG(dbgs() << " -- Analyzing instruction set: [\n"; for (auto *I

607 : Insts) {

608 I->dump();

609 } dbgs() << " ]\n";);

610

611 DenseMap<uint32_t, unsigned> VNums;

612 for (auto *I : Insts) {

613 uint32_t N = VN.lookupOrAdd(I);

615 if (N == ~0U)

616 return std::nullopt;

617 VNums[N]++;

618 }

619 unsigned VNumToSink = llvm::max_element(VNums, llvm::less_second())->first;

620

621 if (VNums[VNumToSink] == 1)

622

623 return std::nullopt;

624

625

626

628 unsigned InitialActivePredSize = ActivePreds.size();

629 SmallVector<Instruction *, 4> NewInsts;

630 for (auto *I : Insts) {

631 if (VN.lookup(I) != VNumToSink)

632 ActivePreds.remove(I->getParent());

633 else

635 }

636 for (auto *I : NewInsts)

637 if (shouldAvoidSinkingInstruction(I))

638 return std::nullopt;

639

640

641

642 bool RecomputePHIContents = false;

643 if (ActivePreds.size() != InitialActivePredSize) {

645 for (auto P : NeededPHIs) {

646 P.restrictToBlocks(ActivePreds);

648 }

649 NeededPHIs = NewNeededPHIs;

651 RecomputePHIContents = true;

652 }

653

654

655 ModelledPHI NewPHI(NewInsts, ActivePreds, RPOTOrder);

656

657

658 if (NeededPHIs.erase(NewPHI))

659 RecomputePHIContents = true;

660

661 if (RecomputePHIContents) {

662

663

664 PHIContents.clear();

665 for (auto &PHI : NeededPHIs)

667 }

668

669

670

671 for (auto *V : NewPHI.getValues())

672 if (PHIContents.count(V))

673

674

675

676 return std::nullopt;

677

678

679

680

682

683 auto isNotSameOperation = [&I0](Instruction *I) {

685 };

686

687 if (any_of(NewInsts, isNotSameOperation))

688 return std::nullopt;

689

690 for (unsigned OpNum = 0, E = I0->getNumOperands(); OpNum != E; ++OpNum) {

691 ModelledPHI PHI(NewInsts, OpNum, ActivePreds);

692 if (PHI.areAllIncomingValuesSame())

693 continue;

695

696 return std::nullopt;

697 if (NeededPHIs.count(PHI))

698 continue;

699 if (PHI.areAllIncomingValuesSameType())

700 return std::nullopt;

701

703 PHI.areAnyIncomingValuesConstant())

704 return std::nullopt;

705

706 NeededPHIs.reserve(NeededPHIs.size());

707 NeededPHIs.insert(PHI);

709 }

710

712 ++MemoryInstNum;

713

714 SinkingInstructionCandidate Cand;

715 Cand.NumInstructions = ++InstNum;

716 Cand.NumMemoryInsts = MemoryInstNum;

717 Cand.NumBlocks = ActivePreds.size();

718 Cand.NumPHIs = NeededPHIs.size();

720

721 return Cand;

722}

723

724unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {

725 LLVM_DEBUG(dbgs() << "GVNSink: running on basic block ";

729

730 if (!RPOTOrder.count(B))

731 return 0;

732 auto *T = B->getTerminator();

734 Preds.push_back(B);

735 else

736 return 0;

737 }

738 if (Preds.size() < 2)

739 return 0;

741 return RPOTOrder.lookup(BB1) < RPOTOrder.lookup(BB2);

742 };

743

745

746 unsigned NumOrigPreds = Preds.size();

747

750 });

751

752 LockstepReverseIterator LRI(Preds);

754 unsigned InstNum = 0, MemoryInstNum = 0;

756 SmallPtrSet<Value *, 4> PHIContents;

757 analyzeInitialPHIs(BBEnd, NeededPHIs, PHIContents);

758 unsigned NumOrigPHIs = NeededPHIs.size();

759

761 auto Cand = analyzeInstructionForSinking(LRI, InstNum, MemoryInstNum,

762 NeededPHIs, PHIContents);

763 if (!Cand)

764 break;

765 Cand->calculateCost(NumOrigPHIs, Preds.size());

767 --LRI;

768 }

769

770 llvm::stable_sort(Candidates, std::greater());

771 LLVM_DEBUG(dbgs() << " -- Sinking candidates:\n"; for (auto &C

772 : Candidates) dbgs()

773 << " " << C << "\n";);

774

775

776 if (Candidates.empty() || Candidates.front().Cost <= 0)

777 return 0;

778 auto C = Candidates.front();

779

782 if (C.Blocks.size() < NumOrigPreds) {

786 if (!InsertBB) {

788

789 return 0;

790 }

791 }

792

793 for (unsigned I = 0; I < C.NumInstructions; ++I)

795

796 return C.NumInstructions;

797}

798

800 BasicBlock *BBEnd) {

801 SmallVector<Instruction *, 4> Insts;

802 for (BasicBlock *BB : Blocks)

805

807 for (unsigned O = 0, E = I0->getNumOperands(); O != E; ++O) {

808 bool NeedPHI = llvm::any_of(Insts, [&I0, O](const Instruction *I) {

809 return I->getOperand(O) != I0->getOperand(O);

810 });

811 if (!NeedPHI) {

813 continue;

814 }

815

816

818 assert(Op->getType()->isTokenTy() && "Can't PHI tokens!");

819 auto *PN =

822 for (auto *I : Insts)

823 PN->addIncoming(I->getOperand(O), I->getParent());

825 }

826

827

828

832

833

834 for (auto *I : Insts)

835 if (I != I0) {

838 }

839

840 for (auto *I : Insts)

841 if (I != I0) {

842 I->replaceAllUsesWith(I0);

844 }

845 foldPointlessPHINodes(BBEnd);

846

847

848 for (auto *I : Insts)

849 if (I != I0)

850 I->eraseFromParent();

851

852 NumRemoved += Insts.size() - 1;

853}

854

856 GVNSink G;

857 if (G.run(F))

859

861}

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

This file defines the BumpPtrAllocator interface.

Atomic ordering constants.

static const Function * getParent(const Value *V)

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

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

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

This file defines the DenseMap class.

This file defines the DenseSet and SmallDenseSet classes.

The header file for the GVN pass that contains expression handling classes.

static bool isMemoryInst(const Instruction *I)

Definition GVNSink.cpp:87

DenseSet< ModelledPHI > ModelledPHISet

Definition GVNSink.cpp:275

This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...

This is the interface for a simple mod/ref and alias analysis over globals.

This file provides various utilities for inspecting and working with the control flow graph in LLVM I...

This header defines various interfaces for pass management in LLVM.

This defines the Use class.

static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)

A Lookup helper functions.

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

uint64_t IntrinsicInst * II

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

static void sinkLastInstruction(ArrayRef< BasicBlock * > Blocks)

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)

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

static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)

Returns the opcode of Values or ~0 if they do not all agree.

Recycle small arrays allocated from a BumpPtrAllocator.

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

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

iterator_range< const_phi_iterator > phis() const

Returns a range that iterates over the phis in the basic block.

LLVM_ABI const_iterator getFirstInsertionPt() const

Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

bool onlyReadsMemory(unsigned OpNo) const

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

This class is the base class for the comparison instructions.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

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

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

Implements a dense probed hash-table based set.

hash_code getHashValue() const override

LLVM_DUMP_METHOD void dump() const

Definition GVNSink.cpp:82

void print(raw_ostream &OS) const

LLVM_ABI bool isSameOperationAs(const Instruction *I, unsigned flags=0) const LLVM_READONLY

This function determines if the specified instruction executes the same operation as the current one.

LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY

Return the number of successors that this instruction has.

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

LLVM_ABI void andIRFlags(const Value *V)

Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction.

LLVM_ABI void moveBefore(InstListType::iterator InsertPos)

Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...

LLVM_ABI void insertBefore(InstListType::iterator InsertPos)

Insert an unlinked instruction into a basic block immediately before the specified position.

LLVM_ABI InstListType::iterator eraseFromParent()

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

LLVM_ABI void applyMergedLocation(DebugLoc LocA, DebugLoc LocB)

Merge 2 debug locations and apply it to the Instruction.

Iterates through instructions in a set of blocks in reverse order from the first non-terminator.

void restrictToBlocks(SmallSetVector< BasicBlock *, 4 > &Blocks)

SmallSetVector< BasicBlock *, 4 > & getActiveBlocks()

void addIncoming(Value *V, BasicBlock *BB)

Add an incoming value to the end of the PHI list.

op_range incoming_values()

BasicBlock * getIncomingBlock(unsigned i) const

Return incoming basic block number i.

Value * getIncomingValue(unsigned i) const

Return incoming value number x.

unsigned getNumIncomingValues() const

Return the number of incoming edges.

static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)

Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...

static LLVM_ABI PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

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

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Recycler - This class manages a linked-list of deallocated nodes and facilitates reusing deallocated ...

void clear(AllocatorType &Allocator)

clear - Release all the tracked allocations to the allocator.

size_type size() const

Determine the number of elements in the SetVector.

bool contains(const_arg_type key) const

Check if the SetVector contains the given key.

This instruction constructs a fixed permutation of two input vectors.

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.

void insert_range(Range &&R)

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

reference emplace_back(ArgTypes &&... Args)

iterator erase(const_iterator CI)

void push_back(const T &Elt)

static Twine utohexstr(uint64_t Val)

LLVM_ABI void set(Value *Val)

const Use & getOperandUse(unsigned i) const

Value * getOperand(unsigned i) const

unsigned getNumOperands() const

LLVM Value Representation.

Type * getType() const

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

LLVM_ABI void replaceAllUsesWith(Value *V)

Change all uses of this to point to a new Value.

LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const

Print the name of this Value out to the specified raw_ostream.

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

An opaque object representing a hash code.

const ParentTy * getParent() const

self_iterator getIterator()

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

SmallVector< ValueIDNum, 0 > ValueTable

Type for a table of values in a block.

unsigned ID

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

@ C

The default llvm calling convention, compatible with C.

raw_ostream & operator<<(raw_ostream &OS, const Expression &E)

@ BasicBlock

Various leaf nodes.

friend class Instruction

Iterator for Instructions in a `BasicBlock.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

void stable_sort(R &&Range)

bool all_of(R &&range, UnaryPredicate P)

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

decltype(auto) dyn_cast(const From &Val)

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

constexpr from_range_t from_range

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

Wrapper function to append range R to container C.

bool isStrongerThanUnordered(AtomicOrdering AO)

bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)

bool any_of(R &&range, UnaryPredicate P)

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

bool operator>(int64_t V1, const APSInt &V2)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

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

bool is_sorted(R &&Range, Compare C)

Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...

class LLVM_GSL_OWNER SmallVector

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

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)

Combine the metadata of two instructions so that K can replace J.

LLVM_ABI BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)

This method introduces at least one new basic block into the function and moves some of the predecess...

LLVM_ABI bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx)

Given an instruction, is it legal to set operand OpIdx to a non-constant value?

DWARFExpression::Operation Op

auto max_element(R &&Range)

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

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

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

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

auto predecessors(const MachineBasicBlock *BB)

bool pred_empty(const BasicBlock *BB)

bool all_equal(std::initializer_list< T > Values)

Returns true if all Values in the initializer lists are equal or the list.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

hash_code hash_combine(const Ts &...args)

Combine values into a single hash_code.

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)

Compute a hash_code for a sequence of values.

static ModelledPHI & getTombstoneKey()

Definition GVNSink.cpp:263

static ModelledPHI & getEmptyKey()

Definition GVNSink.cpp:258

static bool isEqual(const ModelledPHI &LHS, const ModelledPHI &RHS)

Definition GVNSink.cpp:270

static unsigned getHashValue(const ModelledPHI &V)

Definition GVNSink.cpp:268

An information struct used to provide DenseMap with the various necessary components for a given valu...

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

Run the pass over the function.

Definition GVNSink.cpp:855