LLVM: lib/Transforms/IPO/MergeFunctions.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

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

121#include

122#include

123#include

124#include

125#include

126#include

127

128using namespace llvm;

129

130#define DEBUG_TYPE "mergefunc"

131

132STATISTIC(NumFunctionsMerged, "Number of functions merged");

133STATISTIC(NumThunksWritten, "Number of thunks generated");

134STATISTIC(NumAliasesWritten, "Number of aliases generated");

135STATISTIC(NumDoubleWeak, "Number of new functions created");

136

138 "mergefunc-verify",

139 cl::desc("How many functions in a module could be used for "

140 "MergeFunctions to pass a basic correctness check. "

141 "'0' disables this check. Works only with '-debug' key."),

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

161 cl::desc("Preserve debug info in thunk when mergefunc "

162 "transformations are made."));

163

167 cl::desc("Allow mergefunc to create aliases"));

168

169namespace {

170

171class FunctionNode {

174

175public:

176

178

179 Function *getFunc() const { return F; }

180 stable_hash getHash() const { return Hash; }

181

182

183

184 void replaceBy(Function *G) const {

185 F = G;

186 }

187};

188

189

190

191

192

193class MergeFunctions {

194public:

195 MergeFunctions() : FnTree(FunctionNodeCmp(&GlobalNumbers)) {

196 }

197

198 template bool run(FuncContainer &Functions);

200

201 SmallPtrSet<GlobalValue *, 4> &getUsed();

202

203private:

204

205

206 class FunctionNodeCmp {

207 GlobalNumberState* GlobalNumbers;

208

209 public:

210 FunctionNodeCmp(GlobalNumberState* GN) : GlobalNumbers(GN) {}

211

212 bool operator()(const FunctionNode &LHS, const FunctionNode &RHS) const {

213

214 if (LHS.getHash() != RHS.getHash())

215 return LHS.getHash() < RHS.getHash();

216 FunctionComparator FCmp(LHS.getFunc(), RHS.getFunc(), GlobalNumbers);

217 return FCmp.compare() < 0;

218 }

219 };

220 using FnTreeType = std::set<FunctionNode, FunctionNodeCmp>;

221

222 GlobalNumberState GlobalNumbers;

223

224

225

226 std::vector Deferred;

227

228

229 SmallPtrSet<GlobalValue *, 4> Used;

230

231#ifndef NDEBUG

232

233

234 bool doFunctionalCheck(std::vector &Worklist);

235#endif

236

237

238

239 bool insert(Function *NewFunction);

240

241

242

243 void remove(Function *F);

244

245

246

247 void removeUsers(Value *V);

248

249

250

251 void replaceDirectCallers(Function *Old, Function *New);

252

253

254

255

256 void mergeTwoFunctions(Function *F, Function *G);

257

258

259

260

261 void

262 filterInstsUnrelatedToPDI(BasicBlock *GEntryBlock,

263 std::vector<Instruction *> &PDIUnrelatedWL,

264 std::vector<DbgVariableRecord *> &PDVRUnrelatedWL);

265

266

267 void eraseTail(Function *G);

268

269

270

271

272

273 void

274 eraseInstsUnrelatedToPDI(std::vector<Instruction *> &PDIUnrelatedWL,

275 std::vector<DbgVariableRecord *> &PDVRUnrelatedWL);

276

277

278

279

280 void writeThunk(Function *F, Function *G);

281

282

283 void writeAlias(Function *F, Function *G);

284

285

286

287

288 bool writeThunkOrAliasIfNeeded(Function *F, Function *G);

289

290

291 void replaceFunctionInTree(const FunctionNode &FN, Function *G);

292

293

294

295 FnTreeType FnTree;

296

297

298

299

300

301

302 DenseMap<AssertingVH, FnTreeType::iterator> FNodesInTree;

303

304

305 DenseMap<Function *, Function *> DelToNewMap;

306};

307}

308

315

317

319 MergeFunctions MF;

323 MF.getUsed().insert_range(UsedV);

324 return MF.run(M);

325}

326

329 MergeFunctions MF;

330 return MF.runOnFunctions(F);

331}

332

333#ifndef NDEBUG

334bool MergeFunctions::doFunctionalCheck(std::vector &Worklist) {

336 unsigned TripleNumber = 0;

337 bool Valid = true;

338

339 dbgs() << "MERGEFUNC-VERIFY: Started for first " << Max << " functions.\n";

340

341 unsigned i = 0;

342 for (std::vector::iterator I = Worklist.begin(),

343 E = Worklist.end();

344 I != E && i < Max; ++I, ++i) {

345 unsigned j = i;

346 for (std::vector::iterator J = I; J != E && j < Max;

347 ++J, ++j) {

352

353

354 if (Res1 != -Res2) {

355 dbgs() << "MERGEFUNC-VERIFY: Non-symmetric; triple: " << TripleNumber

356 << "\n";

357 dbgs() << *F1 << '\n' << *F2 << '\n';

358 Valid = false;

359 }

360

361 if (Res1 == 0)

362 continue;

363

364 unsigned k = j;

365 for (std::vector::iterator K = J; K != E && k < Max;

366 ++k, ++K, ++TripleNumber) {

367 if (K == J)

368 continue;

369

373

374 bool Transitive = true;

375

376 if (Res1 != 0 && Res1 == Res4) {

377

378 Transitive = Res3 == Res1;

379 } else if (Res3 != 0 && Res3 == -Res4) {

380

381 Transitive = Res3 == Res1;

382 } else if (Res4 != 0 && -Res3 == Res4) {

383

384 Transitive = Res4 == -Res1;

385 }

386

387 if (!Transitive) {

388 dbgs() << "MERGEFUNC-VERIFY: Non-transitive; triple: "

389 << TripleNumber << "\n";

390 dbgs() << "Res1, Res3, Res4: " << Res1 << ", " << Res3 << ", "

391 << Res4 << "\n";

392 dbgs() << *F1 << '\n' << *F2 << '\n' << *F3 << '\n';

394 }

395 }

396 }

397 }

398

399 dbgs() << "MERGEFUNC-VERIFY: " << (Valid ? "Passed." : "Failed.") << "\n";

401 }

402 return true;

403}

404#endif

405

406

407

408

411 for (const Instruction &I : BB.instructionsWithoutDebug()) {

413 continue;

414

415 for (Value *Op : I.operands()) {

417 if (!MDL)

418 continue;

420 if (N->isDistinct())

421 return true;

422 }

423 }

424 }

425 return false;

426}

427

428

430 return F.isDeclaration() && F.hasAvailableExternallyLinkage() &&

432}

433

436

437template bool MergeFunctions::run(FuncContainer &M) {

439

440

441

442 std::vector<std::pair<stable_hash, Function *>> HashedFuncs;

443 for (auto &Func : M) {

446 HashedFuncs.push_back({StructuralHash(*FuncPtr), FuncPtr});

447 }

448 }

449

451

452 auto S = HashedFuncs.begin();

453 for (auto I = HashedFuncs.begin(), IE = HashedFuncs.end(); I != IE; ++I) {

454

455

456 if ((I != S && std::prev(I)->first == I->first) ||

457 (std::next(I) != IE && std::next(I)->first == I->first)) {

459 }

460 }

461

462 do {

463 std::vector Worklist;

464 Deferred.swap(Worklist);

465

466 LLVM_DEBUG(doFunctionalCheck(Worklist));

467

468 LLVM_DEBUG(dbgs() << "size of module: " << M.size() << '\n');

469 LLVM_DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n');

470

471

473 if (I)

474 continue;

476 if (F->isDeclaration() && F->hasAvailableExternallyLinkage()) {

478 }

479 }

480 LLVM_DEBUG(dbgs() << "size of FnTree: " << FnTree.size() << '\n');

481 } while (!Deferred.empty());

482

483 FnTree.clear();

484 FNodesInTree.clear();

485 GlobalNumbers.clear();

486 Used.clear();

487

489}

490

493 [[maybe_unused]] bool MergeResult = this->run(F);

494 assert(MergeResult == !DelToNewMap.empty());

495 return this->DelToNewMap;

496}

497

498

499void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {

502 if (CB && CB->isCallee(&U)) {

503

504

505

506

508 U.set(New);

509 }

510 }

511}

512

513

514

515void MergeFunctions::eraseInstsUnrelatedToPDI(

516 std::vector<Instruction *> &PDIUnrelatedWL,

517 std::vector<DbgVariableRecord *> &PDVRUnrelatedWL) {

519 dbgs() << " Erasing instructions (in reverse order of appearance in "

520 "entry block) unrelated to parameter debug info from entry "

521 "block: {\n");

522 while (!PDIUnrelatedWL.empty()) {

527 I->eraseFromParent();

528 PDIUnrelatedWL.pop_back();

529 }

530

531 while (!PDVRUnrelatedWL.empty()) {

533 LLVM_DEBUG(dbgs() << " Deleting DbgVariableRecord ");

537 PDVRUnrelatedWL.pop_back();

538 }

539

540 LLVM_DEBUG(dbgs() << " } // Done erasing instructions unrelated to parameter "

541 "debug info from entry block. \n");

542}

543

544

545void MergeFunctions::eraseTail(Function *G) {

546 std::vector<BasicBlock *> WorklistBB;

548 BB.dropAllReferences();

549 WorklistBB.push_back(&BB);

550 }

551 while (!WorklistBB.empty()) {

554 WorklistBB.pop_back();

555 }

556}

557

558

559

560

561

562

563

564

565

566

567void MergeFunctions::filterInstsUnrelatedToPDI(

568 BasicBlock *GEntryBlock, std::vector<Instruction *> &PDIUnrelatedWL,

569 std::vector<DbgVariableRecord *> &PDVRUnrelatedWL) {

570 std::set<Instruction *> PDIRelated;

571 std::set<DbgVariableRecord *> PDVRRelated;

572

573

574

575 auto ExamineDbgValue = [&PDVRRelated](DbgVariableRecord *DbgVal) {

584 PDVRRelated.insert(DbgVal);

585 } else {

589 }

590 };

591

592 auto ExamineDbgDeclare = [&PDIRelated,

602 if (AI) {

607 if (Value *Arg = SI->getValueOperand()) {

612 PDIRelated.insert(AI);

616 PDIRelated.insert(SI);

620 PDVRRelated.insert(DbgDecl);

621 } else {

625 }

626 }

627 } else {

631 }

632 }

633 } else {

637 }

638 } else {

642 }

643 };

644

646 BI != BIE; ++BI) {

647

648

651 ExamineDbgValue(&DVR);

652 } else {

654 ExamineDbgDeclare(&DVR);

655 }

656 }

657

658 if (BI->isTerminator() && &*BI == GEntryBlock->getTerminator()) {

662 PDIRelated.insert(&*BI);

663 } else {

667 }

668 }

671 << " Report parameter debug info related/related instructions: {\n");

672

673 auto IsPDIRelated = [](auto *Rec, auto &Container, auto &UnrelatedCont) {

674 if (Container.find(Rec) == Container.end()) {

678 UnrelatedCont.push_back(Rec);

679 } else {

683 }

684 };

685

686

689 IsPDIRelated(&DVR, PDVRRelated, PDVRUnrelatedWL);

690 IsPDIRelated(&I, PDIRelated, PDIUnrelatedWL);

691 }

693}

694

695

697 if (F->isVarArg())

698 return false;

699

700

701

702 if (F->size() == 1) {

703 if (F->front().sizeWithoutDebug() < 2) {

704 LLVM_DEBUG(dbgs() << "canCreateThunkFor: " << F->getName()

705 << " is too small to bother creating a thunk for\n");

706 return false;

707 }

708 }

709 return true;

710}

711

712

717 for (MDNode *MD : MDs)

719}

720

721

722

723

724

725

726

727

728

731 std::vector<Instruction *> PDIUnrelatedWL;

732 std::vector<DbgVariableRecord *> PDVRUnrelatedWL;

736 LLVM_DEBUG(dbgs() << "writeThunk: (MergeFunctionsPDI) Do not create a new "

737 "function as thunk; retain original: "

738 << G->getName() << "()\n");

739 GEntryBlock = &G->getEntryBlock();

741 dbgs() << "writeThunk: (MergeFunctionsPDI) filter parameter related "

742 "debug info for "

743 << G->getName() << "() {\n");

744 filterInstsUnrelatedToPDI(GEntryBlock, PDIUnrelatedWL, PDVRUnrelatedWL);

746 BB = GEntryBlock;

747 } else {

749 G->getAddressSpace(), "", G->getParent());

752 }

753

757 unsigned i = 0;

760 Args.push_back(Builder.CreateAggregateCast(&AI, FFTy->getParamType(i)));

761 ++i;

762 }

763

764 CallInst *CI = Builder.CreateCall(F, Args);

772 if (H->getReturnType()->isVoidTy()) {

773 RI = Builder.CreateRetVoid();

774 } else {

775 RI = Builder.CreateRet(Builder.CreateAggregateCast(CI, H->getReturnType()));

776 }

777

780 if (DIS) {

787 } else {

789 dbgs() << "writeThunk: (MergeFunctionsPDI) No DISubprogram for "

790 << G->getName() << "()\n");

791 }

792 eraseTail(G);

793 eraseInstsUnrelatedToPDI(PDIUnrelatedWL, PDVRUnrelatedWL);

795 dbgs() << "} // End of parameter related debug info filtering for: "

796 << G->getName() << "()\n");

797 } else {

800

803 removeUsers(G);

804 G->replaceAllUsesWith(NewG);

805 G->eraseFromParent();

806 }

807

808 LLVM_DEBUG(dbgs() << "writeThunk: " << H->getName() << '\n');

809 ++NumThunksWritten;

810}

811

812

815 return false;

816

817

818 assert(F->hasLocalLinkage() || F->hasExternalLinkage()

819 || F->hasWeakLinkage() || F->hasLinkOnceLinkage());

820 return true;

821}

822

823

826 auto *GA = GlobalAlias::create(G->getValueType(), PtrType->getAddressSpace(),

827 G->getLinkage(), "", F, G->getParent());

828

831 if (FAlign || GAlign)

833 else

834 F->setAlignment(std::nullopt);

835 GA->takeName(G);

836 GA->setVisibility(G->getVisibility());

838

839 removeUsers(G);

840 G->replaceAllUsesWith(GA);

841 G->eraseFromParent();

842

843 LLVM_DEBUG(dbgs() << "writeAlias: " << GA->getName() << '\n');

844 ++NumAliasesWritten;

845}

846

847

848

849

850bool MergeFunctions::writeThunkOrAliasIfNeeded(Function *F, Function *G) {

851 if (G->isDiscardableIfUnused() && G->use_empty() && MergeFunctionsPDI) {

852 G->eraseFromParent();

853 return true;

854 }

856 writeAlias(F, G);

857 return true;

858 }

860 writeThunk(F, G);

861 return true;

862 }

863 return false;

864}

865

866

868 return F->hasWeakODRLinkage() || F->hasLinkOnceODRLinkage();

869}

870

871

873

874

875

876

877 if (F->isInterposable() || (isODR(F) && isODR(G))) {

879 "if G is ODR, F must also be ODR due to ordering");

880

881

882

883

884

887 return;

888

889

891 F->getAddressSpace(), "", F->getParent());

895 F->setComdat(nullptr);

896

899 removeUsers(F);

900 F->replaceAllUsesWith(NewF);

901

902

903

905 replaceDirectCallers(G, F);

907 replaceDirectCallers(NewF, F);

908

909

910

913

914 writeThunkOrAliasIfNeeded(F, G);

915 writeThunkOrAliasIfNeeded(F, NewF);

916

917 if (NewFAlign || GAlign)

919 else

920 F->setAlignment(std::nullopt);

922 ++NumDoubleWeak;

923 ++NumFunctionsMerged;

924 } else {

925

926

928

929

930

931 if (G->hasGlobalUnnamedAddr() && Used.contains(G)) {

932

933

934 GlobalNumbers.erase(G);

935

936 removeUsers(G);

937 G->replaceAllUsesWith(F);

938 } else {

939

940

941 replaceDirectCallers(G, F);

942 }

943 }

944

945

946

947

948 if (G->isDiscardableIfUnused() && G->use_empty() && MergeFunctionsPDI) {

949 G->eraseFromParent();

950 ++NumFunctionsMerged;

951 return;

952 }

953

954 if (writeThunkOrAliasIfNeeded(F, G)) {

955 ++NumFunctionsMerged;

956 }

957 }

958}

959

960

961void MergeFunctions::replaceFunctionInTree(const FunctionNode &FN,

965 "The two functions must be equal");

966

967 auto I = FNodesInTree.find(F);

968 assert(I != FNodesInTree.end() && "F should be in FNodesInTree");

969 assert(FNodesInTree.count(G) == 0 && "FNodesInTree should not contain G");

970

971 FnTreeType::iterator IterToFNInFnTree = I->second;

972 assert(&(*IterToFNInFnTree) == &FN && "F should map to FN in FNodesInTree.");

973

974 FNodesInTree.erase(I);

975 FNodesInTree.insert({G, IterToFNInFnTree});

976

977 FN.replaceBy(G);

978}

979

980

983

984

986 }

987

988 if (F->isInterposable() != G->isInterposable()) {

989

990

991 return F->isInterposable();

992 }

993

994 if (F->hasLocalLinkage() != G->hasLocalLinkage()) {

995

996

997 return F->hasLocalLinkage();

998 }

999

1000

1001

1002

1003 return F->getName() <= G->getName();

1004}

1005

1006

1007

1008bool MergeFunctions::insert(Function *NewFunction) {

1009 std::pair<FnTreeType::iterator, bool> Result =

1010 FnTree.insert(FunctionNode(NewFunction));

1011

1012 if (Result.second) {

1013 assert(FNodesInTree.count(NewFunction) == 0);

1014 FNodesInTree.insert({NewFunction, Result.first});

1016 << '\n');

1017 return false;

1018 }

1019

1020 const FunctionNode &OldF = *Result.first;

1021

1023

1025 replaceFunctionInTree(*Result.first, NewFunction);

1026 NewFunction = F;

1027 assert(OldF.getFunc() != F && "Must have swapped the functions.");

1028 }

1029

1030 LLVM_DEBUG(dbgs() << " " << OldF.getFunc()->getName()

1031 << " == " << NewFunction->getName() << '\n');

1032

1033 Function *DeleteF = NewFunction;

1034 mergeTwoFunctions(OldF.getFunc(), DeleteF);

1035 this->DelToNewMap.insert({DeleteF, OldF.getFunc()});

1036 return true;

1037}

1038

1039

1040

1041void MergeFunctions::remove(Function *F) {

1042 auto I = FNodesInTree.find(F);

1043 if (I != FNodesInTree.end()) {

1044 LLVM_DEBUG(dbgs() << "Deferred " << F->getName() << ".\n");

1045 FnTree.erase(I->second);

1046

1047

1048 FNodesInTree.erase(I);

1049 Deferred.emplace_back(F);

1050 }

1051}

1052

1053

1054

1055void MergeFunctions::removeUsers(Value *V) {

1056 for (User *U : V->users())

1058 remove(I->getFunction());

1059}

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

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

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

This defines the Use class.

static bool canCreateAliasFor(Function *F)

Definition MergeFunctions.cpp:813

static bool isEligibleForMerging(Function &F)

Check whether F is eligible for function merging.

Definition MergeFunctions.cpp:429

static bool isODR(const Function *F)

Returns true if F is either weak_odr or linkonce_odr.

Definition MergeFunctions.cpp:867

static cl::opt< unsigned > NumFunctionsForVerificationCheck("mergefunc-verify", cl::desc("How many functions in a module could be used for " "MergeFunctions to pass a basic correctness check. " "'0' disables this check. Works only with '-debug' key."), cl::init(0), cl::Hidden)

static bool canCreateThunkFor(Function *F)

Whether this function may be replaced by a forwarding thunk.

Definition MergeFunctions.cpp:696

static cl::opt< bool > MergeFunctionsPDI("mergefunc-preserve-debug-info", cl::Hidden, cl::init(false), cl::desc("Preserve debug info in thunk when mergefunc " "transformations are made."))

static bool hasDistinctMetadataIntrinsic(const Function &F)

Check whether F has an intrinsic which references distinct metadata as an operand.

Definition MergeFunctions.cpp:409

Function * asPtr(Function *Fn)

Definition MergeFunctions.cpp:434

static void copyMetadataIfPresent(Function *From, Function *To, StringRef Kind)

Copy all metadata of a specific kind from one function to another.

Definition MergeFunctions.cpp:713

static cl::opt< bool > MergeFunctionsAliases("mergefunc-use-aliases", cl::Hidden, cl::init(false), cl::desc("Allow mergefunc to create aliases"))

static bool isFuncOrderCorrect(const Function *F, const Function *G)

Definition MergeFunctions.cpp:981

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)

an instruction to allocate memory on the stack

This class represents an incoming formal argument to a Function.

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

Value handle that asserts if the Value is deleted.

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)

Creates a new BasicBlock.

LLVM_ABI SymbolTableList< BasicBlock >::iterator eraseFromParent()

Unlink 'this' from the containing function and delete it.

InstListType::iterator iterator

Instruction iterators...

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

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

void setCallingConv(CallingConv::ID CC)

bool isCallee(Value::const_user_iterator UI) const

Determine whether the passed iterator points to the callee operand's Use.

void setAttributes(AttributeList A)

Set the attributes for this call.

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

void setTailCallKind(TailCallKind TCK)

LLVM_ABI DISubprogram * getSubprogram() const

Get the subprogram for this scope.

Subprogram description. Uses SubclassData1.

LLVM_ABI void eraseFromParent()

Record of a variable value-assignment, aka a non instruction representation of the dbg....

LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const

bool isDbgDeclare() const

FunctionComparator - Compares two functions to determine whether or not they will generate machine co...

LLVM_ABI int compare()

Test whether the two functions have equivalent behaviour.

Class to represent function types.

static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)

MaybeAlign getAlign() const

Returns the alignment of the given function.

void copyAttributesFrom(const Function *Src)

copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...

static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)

If a parent module is specified, the alias is automatically inserted into the end of the specified mo...

void erase(GlobalValue *Global)

LLVM_ABI void setComdat(Comdat *C)

LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)

Add a metadata attachment.

MDNode * getMetadata(unsigned KindID) const

Get the current metadata attachments for the given kind, if any.

@ PrivateLinkage

Like Internal, but omit from symbol table.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

LLVM_ABI InstListType::iterator eraseFromParent()

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

LLVM_ABI const Function * getFunction() const

Return the function this instruction belongs to.

void setDebugLoc(DebugLoc Loc)

Set the debug location information for this instruction.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

LLVMContext & getContext() const

static LLVM_ABI DenseMap< Function *, Function * > runOnFunctions(ArrayRef< Function * > F)

Definition MergeFunctions.cpp:328

static LLVM_ABI bool runOnModule(Module &M)

Definition MergeFunctions.cpp:318

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

Definition MergeFunctions.cpp:309

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

Class to represent pointers.

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.

Return a value (possibly void), from a function.

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

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

An instruction for storing to memory.

StringRef - Represent a constant reference to a string, i.e.

A Use represents the edge between a Value definition and its users.

LLVM Value Representation.

LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const

Implement operator<< on Value.

iterator_range< user_iterator > users()

iterator_range< use_iterator > uses()

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

LLVM_ABI void takeName(Value *V)

Transfer the name from V to this value.

Value handle that is nullable, but tries to track the Value.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

@ SwiftTail

This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...

int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)

Compare two scaled numbers.

@ Valid

The data is already valid.

initializer< Ty > init(const Ty &Val)

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)

Remove path.

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

void stable_sort(R &&Range)

decltype(auto) dyn_cast(const From &Val)

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

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

uint64_t stable_hash

An opaque object representing a stable hash code.

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI raw_ostream & dbgs()

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

bool isa(const From &Val)

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

DWARFExpression::Operation Op

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

decltype(auto) cast(const From &Val)

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

static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)

Filter the DbgRecord range to DbgVariableRecord types only and downcast.

LLVM_ABI stable_hash StructuralHash(const Function &F, bool DetailedHash=false)

Returns a hash of the function F.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

LLVM_ABI GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)

Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.

Align valueOrOne() const

For convenience, returns a valid alignment or 1 if undefined.

Function object to check whether the first component of a container supported by std::get (like std::...