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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

31

32using namespace llvm;

33

34#define DEBUG_TYPE "globalsmodref-aa"

35

37 "Number of global vars without address taken");

38STATISTIC(NumNonAddrTakenFunctions,"Number of functions without address taken");

39STATISTIC(NumNoMemFunctions, "Number of functions that do not access memory");

40STATISTIC(NumReadMemFunctions, "Number of functions that only read memory");

41STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");

42

43

44

45

46

47

48

49

50

51

52

53

55 "enable-unsafe-globalsmodref-alias-results", cl::init(false), cl::Hidden);

56

57

58

59

60

61

62

65

66

67

68

69 struct alignas(8) AlignedMap {

70 AlignedMap() = default;

71 AlignedMap(const AlignedMap &Arg) = default;

73 };

74

75

76 struct AlignedMapPointerTraits {

77 static inline void *getAsVoidPointer(AlignedMap *P) { return P; }

78 static inline AlignedMap *getFromVoidPointer(void *P) {

79 return (AlignedMap *)P;

80 }

81 static constexpr int NumLowBitsAvailable = 3;

82 static_assert(alignof(AlignedMap) >= (1 << NumLowBitsAvailable),

83 "AlignedMap insufficiently aligned to have enough low bits.");

84 };

85

86

87

88

89

90

91 enum { MayReadAnyGlobal = 4 };

92

93

94 static_assert((MayReadAnyGlobal & static_cast<int>(ModRefInfo::ModRef)) == 0,

95 "ModRef and the MayReadAnyGlobal flag bits overlap.");

96 static_assert(((MayReadAnyGlobal | static_cast<int>(ModRefInfo::ModRef)) >>

97 AlignedMapPointerTraits::NumLowBitsAvailable) == 0,

98 "Insufficient low bits to store our flag and ModRef info.");

99

100public:

104 }

105

106

107

109 : Info(nullptr, Arg.Info.getInt()) {

110 if (const auto *ArgPtr = Arg.Info.getPointer())

111 Info.setPointer(new AlignedMap(*ArgPtr));

112 }

114 : Info(Arg.Info.getPointer(), Arg.Info.getInt()) {

115 Arg.Info.setPointerAndInt(nullptr, 0);

116 }

120 if (const auto *RHSPtr = RHS.Info.getPointer())

121 Info.setPointer(new AlignedMap(*RHSPtr));

122 return *this;

123 }

127 RHS.Info.setPointerAndInt(nullptr, 0);

128 return *this;

129 }

130

131

132

135 }

136

137

140 }

141

142

144 Info.setInt(Info.getInt() | static_cast<int>(NewMRI));

145 }

146

147

148

150

151

153

154

155

160 auto I = P->Map.find(&GV);

161 if (I != P->Map.end())

162 GlobalMRI |= I->second;

163 }

164 return GlobalMRI;

165 }

166

167

168

171

174

175 if (AlignedMap *P = FI.Info.getPointer())

176 for (const auto &G : P->Map)

178 }

179

182 if (P) {

183 P = new AlignedMap();

185 }

186 auto &GlobalMRI = P->Map[&GV];

187 GlobalMRI |= NewMRI;

188 }

189

190

191

194 P->Map.erase(&GV);

195 }

196

197private:

198

199

200

201

202

204};

205

206void GlobalsAAResult::DeletionCallbackHandle::deleted() {

207 Value *V = getValPtr();

208 if (auto *F = dyn_cast(V))

209 GAR->FunctionInfos.erase(F);

210

211 if (GlobalValue *GV = dyn_cast(V)) {

212 if (GAR->NonAddressTakenGlobals.erase(GV)) {

213

214

215 if (GAR->IndirectGlobals.erase(GV)) {

216

217 for (auto I = GAR->AllocsForIndirectGlobals.begin(),

218 E = GAR->AllocsForIndirectGlobals.end();

219 I != E; ++I)

220 if (I->second == GV)

221 GAR->AllocsForIndirectGlobals.erase(I);

222 }

223

224

225

226 for (auto &FIPair : GAR->FunctionInfos)

227 FIPair.second.eraseModRefInfoForGlobal(*GV);

228 }

229 }

230

231

232 GAR->AllocsForIndirectGlobals.erase(V);

233

234

235 setValPtr(nullptr);

236 GAR->Handles.erase(I);

237

238}

239

243

245}

246

247

248

250GlobalsAAResult::getFunctionInfo(const Function *F) {

251 auto I = FunctionInfos.find(F);

252 if (I != FunctionInfos.end())

253 return &I->second;

254 return nullptr;

255}

256

257

258

259

260

261void GlobalsAAResult::AnalyzeGlobals(Module &M) {

264 if (F.hasLocalLinkage()) {

265 if (!AnalyzeUsesOfPointer(&F)) {

266

267 NonAddressTakenGlobals.insert(&F);

268 TrackedFunctions.insert(&F);

269 Handles.emplace_front(*this, &F);

270 Handles.front().I = Handles.begin();

271 ++NumNonAddrTakenFunctions;

272 } else

273 UnknownFunctionsWithLocalLinkage = true;

274 }

275

278 if (GV.hasLocalLinkage()) {

279 if (!AnalyzeUsesOfPointer(&GV, &Readers,

280 GV.isConstant() ? nullptr : &Writers)) {

281

282 NonAddressTakenGlobals.insert(&GV);

283 Handles.emplace_front(*this, &GV);

284 Handles.front().I = Handles.begin();

285

286 for (Function *Reader : Readers) {

287 if (TrackedFunctions.insert(Reader).second) {

288 Handles.emplace_front(*this, Reader);

289 Handles.front().I = Handles.begin();

290 }

291 FunctionInfos[Reader].addModRefInfoForGlobal(GV, ModRefInfo::Ref);

292 }

293

294 if (!GV.isConstant())

295 for (Function *Writer : Writers) {

296 if (TrackedFunctions.insert(Writer).second) {

297 Handles.emplace_front(*this, Writer);

298 Handles.front().I = Handles.begin();

299 }

300 FunctionInfos[Writer].addModRefInfoForGlobal(GV, ModRefInfo::Mod);

301 }

302 ++NumNonAddrTakenGlobalVars;

303

304

305 if (GV.getValueType()->isPointerTy() &&

306 AnalyzeIndirectGlobalMemory(&GV))

307 ++NumIndirectGlobalVars;

308 }

309 Readers.clear();

310 Writers.clear();

311 }

312}

313

314

315

316

317

318

319

320bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,

324 if (V->getType()->isPointerTy())

325 return true;

326

327 for (Use &U : V->uses()) {

328 User *I = U.getUser();

329 if (LoadInst *LI = dyn_cast(I)) {

330 if (Readers)

331 Readers->insert(LI->getParent()->getParent());

332 } else if (StoreInst *SI = dyn_cast(I)) {

333 if (V == SI->getOperand(1)) {

334 if (Writers)

335 Writers->insert(SI->getParent()->getParent());

336 } else if (SI->getOperand(1) != OkayStoreDest) {

337 return true;

338 }

340 if (AnalyzeUsesOfPointer(I, Readers, Writers))

341 return true;

344 if (AnalyzeUsesOfPointer(I, Readers, Writers, OkayStoreDest))

345 return true;

346 } else if (auto *Call = dyn_cast(I)) {

348 if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&

349 V == II->getArgOperand(0)) {

350 if (AnalyzeUsesOfPointer(II, Readers, Writers))

351 return true;

352 continue;

353 }

354 }

355

356

357 if (Call->isDataOperand(&U)) {

358

359 if (Call->isArgOperand(&U) &&

361 if (Writers)

362 Writers->insert(Call->getParent()->getParent());

363 } else {

364

365

366

367 auto *F = Call->getCalledFunction();

368

369

370

371

372 if (F || F->isDeclaration())

373 return true;

374

375

376

377

378 if (Call->hasFnAttr(Attribute::NoCallback) ||

379 Call->isArgOperand(&U) ||

380 Call->doesNotCapture(Call->getArgOperandNo(&U)))

381 return true;

382

383

384

385 if (Readers)

386 Readers->insert(Call->getParent()->getParent());

387 if (Writers)

388 Writers->insert(Call->getParent()->getParent());

389 }

390 }

391 } else if (ICmpInst *ICI = dyn_cast(I)) {

392 if (!isa(ICI->getOperand(1)))

393 return true;

394 } else if (Constant *C = dyn_cast(I)) {

395

396 if (isa(C) || C->isConstantUsed())

397 return true;

398 } else {

399 return true;

400 }

401 }

402

403 return false;

404}

405

406

407

408

409

410

411

412

413bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) {

414

415

416 std::vector<Value *> AllocRelatedValues;

417

418

420 if (C->isNullValue())

421 return false;

422

423

424

426 if (LoadInst *LI = dyn_cast(U)) {

427

428

429

430 if (AnalyzeUsesOfPointer(LI))

431 return false;

432

433 } else if (StoreInst *SI = dyn_cast(U)) {

434

435 if (SI->getOperand(0) == GV)

436 return false;

437

438

439 if (isa(SI->getOperand(0)))

440 continue;

441

442

444

446 return false;

447

448

449

450 if (AnalyzeUsesOfPointer(Ptr, nullptr, nullptr,

451 GV))

452 return false;

453

454

455 AllocRelatedValues.push_back(Ptr);

456 } else {

457

458 return false;

459 }

460 }

461

462

463

464 while (!AllocRelatedValues.empty()) {

465 AllocsForIndirectGlobals[AllocRelatedValues.back()] = GV;

466 Handles.emplace_front(*this, AllocRelatedValues.back());

467 Handles.front().I = Handles.begin();

468 AllocRelatedValues.pop_back();

469 }

470 IndirectGlobals.insert(GV);

471 Handles.emplace_front(*this, GV);

472 Handles.front().I = Handles.begin();

473 return true;

474}

475

476void GlobalsAAResult::CollectSCCMembership(CallGraph &CG) {

477

478

479 unsigned SCCID = 0;

481 const std::vector<CallGraphNode *> &SCC = *I;

482 assert(SCC.empty() && "SCC with no functions?");

483

484 for (auto *CGN : SCC)

485 if (Function *F = CGN->getFunction())

486 FunctionToSCCMap[F] = SCCID;

487 ++SCCID;

488 }

489}

490

491

492

493

494

495void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {

496

497

499 const std::vector<CallGraphNode *> &SCC = *I;

500 assert(SCC.empty() && "SCC with no functions?");

501

503

504 if (F || F->isDefinitionExact()) {

505

506

507

508 for (auto *Node : SCC)

509 FunctionInfos.erase(Node->getFunction());

510 continue;

511 }

512

513 FunctionInfo &FI = FunctionInfos[F];

514 Handles.emplace_front(*this, F);

515 Handles.front().I = Handles.begin();

516 bool KnowNothing = false;

517

518

519

520

521

522

523

524

525 auto MaySyncOrCallIntoModule = [](const Function &F) {

526 return F.isDeclaration() || F.hasNoSync() ||

527 F.hasFnAttribute(Attribute::NoCallback);

528 };

529

530

531

532 for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) {

533 if (F) {

534 KnowNothing = true;

535 break;

536 }

537

538 if (F->isDeclaration() || F->hasOptNone()) {

539

540 if (F->doesNotAccessMemory()) {

541

542 } else if (F->onlyReadsMemory()) {

544 if (F->onlyAccessesArgMemory() && MaySyncOrCallIntoModule(*F))

545

546

547 FI.setMayReadAnyGlobal();

548 } else {

550 if (F->onlyAccessesArgMemory())

551 FI.setMayReadAnyGlobal();

552 if (MaySyncOrCallIntoModule(*F)) {

553 KnowNothing = true;

554 break;

555 }

556 }

557 continue;

558 }

559

561 CI != E && !KnowNothing; ++CI)

563 if (FunctionInfo *CalleeFI = getFunctionInfo(Callee)) {

564

565 FI.addFunctionInfo(*CalleeFI);

566 } else {

567

568

571 KnowNothing = true;

572 }

573 } else {

574 KnowNothing = true;

575 }

576 }

577

578

579

580 if (KnowNothing) {

581 for (auto *Node : SCC)

582 FunctionInfos.erase(Node->getFunction());

583 continue;

584 }

585

586

587 for (auto *Node : SCC) {

589 break;

590

591

592

593

594 if (Node->getFunction()->hasOptNone())

595 continue;

596

599 break;

600

601

602

603 if (isa(&I))

604 continue;

605

606

607

608 if (I.mayReadFromMemory())

610 if (I.mayWriteToMemory())

612 }

613 }

614

615 if (isModSet(FI.getModRefInfo()))

616 ++NumReadMemFunctions;

618 ++NumNoMemFunctions;

619

620

621

622

623

624 FunctionInfo CachedFI = FI;

625 for (unsigned i = 1, e = SCC.size(); i != e; ++i)

626 FunctionInfos[SCC[i]->getFunction()] = CachedFI;

627 }

628}

629

630

631

632

641 do {

643

644 if (isa(Input) || isa(Input) || isa(Input) ||

645 isa(Input))

646

647

648

649

650

651

652 continue;

653

654

655

656

657

659 return false;

660

661 if (auto *LI = dyn_cast(Input)) {

663 continue;

664 }

665 if (auto *SI = dyn_cast(Input)) {

672 continue;

673 }

674 if (auto *PN = dyn_cast(Input)) {

675 for (const Value *Op : PN->incoming_values()) {

677 if (Visited.insert(Op).second)

679 }

680 continue;

681 }

682

683 return false;

684 } while (!Inputs.empty());

685

686

687 return true;

688}

689

690

691

692

693

694

695

696

697

698

699

700

701

702

703

704

705

706

707

708

709

710

711

712

713

714

715bool GlobalsAAResult::isNonEscapingGlobalNoAlias(const GlobalValue *GV,

716 const Value *V) {

717

718

719

720

721

722

728 do {

730

731 if (auto *InputGV = dyn_cast(Input)) {

732

733

734 if (InputGV == GV)

735 return false;

736

737

738

739 auto *GVar = dyn_cast(GV);

740 auto *InputGVar = dyn_cast(InputGV);

741 if (GVar && InputGVar &&

742 !GVar->isDeclaration() && !InputGVar->isDeclaration() &&

743 !GVar->isInterposable() && !InputGVar->isInterposable()) {

744 Type *GVType = GVar->getInitializer()->getType();

745 Type *InputGVType = InputGVar->getInitializer()->getType();

749 continue;

750 }

751

752

753

754 return false;

755 }

756

757 if (isa(Input) || isa(Input) ||

758 isa(Input)) {

759

760

761

762 continue;

763 }

764

765

766

767

768

770 return false;

771

772 if (auto *LI = dyn_cast(Input)) {

773

774

777

778 continue;

779

780 return false;

781 }

782 if (auto *SI = dyn_cast(Input)) {

785 if (Visited.insert(LHS).second)

787 if (Visited.insert(RHS).second)

789 continue;

790 }

791 if (auto *PN = dyn_cast(Input)) {

792 for (const Value *Op : PN->incoming_values()) {

794 if (Visited.insert(Op).second)

796 }

797 continue;

798 }

799

800

801

802

803 return false;

804 } while (!Inputs.empty());

805

806

807 return true;

808}

809

812

813

815 return !PAC.preservedWhenStateless();

816}

817

818

819

820

824

825 const Value *UV1 =

827 const Value *UV2 =

829

830

831

832 const GlobalValue *GV1 = dyn_cast(UV1);

833 const GlobalValue *GV2 = dyn_cast(UV2);

834 if (GV1 || GV2) {

835

836

837 if (GV1 && !NonAddressTakenGlobals.count(GV1))

838 GV1 = nullptr;

839 if (GV2 && !NonAddressTakenGlobals.count(GV2))

840 GV2 = nullptr;

841

842

843

844 if (GV1 && GV2 && GV1 != GV2)

846

847

848

849

851 if ((GV1 || GV2) && GV1 != GV2)

853

854

855

856 if ((GV1 || GV2) && GV1 != GV2) {

858 const Value *UV = GV1 ? UV2 : UV1;

859 if (isNonEscapingGlobalNoAlias(GV, UV))

861 }

862

863

864

865 }

866

867

868

869

870 GV1 = GV2 = nullptr;

871 if (const LoadInst *LI = dyn_cast(UV1))

872 if (GlobalVariable *GV = dyn_cast(LI->getOperand(0)))

873 if (IndirectGlobals.count(GV))

874 GV1 = GV;

875 if (const LoadInst *LI = dyn_cast(UV2))

876 if (const GlobalVariable *GV = dyn_cast(LI->getOperand(0)))

877 if (IndirectGlobals.count(GV))

878 GV2 = GV;

879

880

881

882 if (!GV1)

883 GV1 = AllocsForIndirectGlobals.lookup(UV1);

884 if (!GV2)

885 GV2 = AllocsForIndirectGlobals.lookup(UV2);

886

887

888

889

890 if (GV1 && GV2 && GV1 != GV2)

892

893

894

895

897 if ((GV1 || GV2) && GV1 != GV2)

899

901}

902

903ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,

906 if (Call->doesNotAccessMemory())

910

911

912

913 for (const auto &A : Call->args()) {

916

917

919

924 }))

925 return ConservativeResult;

926

928 return ConservativeResult;

929 }

930

931

933}

934

939

940

941

944

945

946 if (GV->hasLocalLinkage() && !UnknownFunctionsWithLocalLinkage)

947 if (const Function *F = Call->getCalledFunction())

948 if (NonAddressTakenGlobals.count(GV))

950 Known = FI->getModRefInfoForGlobal(*GV) |

951 getModRefInfoForArgument(Call, GV, AAQI);

952

953 return Known;

954}

955

956GlobalsAAResult::GlobalsAAResult(

960

963 NonAddressTakenGlobals(std::move(Arg.NonAddressTakenGlobals)),

964 IndirectGlobals(std::move(Arg.IndirectGlobals)),

965 AllocsForIndirectGlobals(std::move(Arg.AllocsForIndirectGlobals)),

966 FunctionInfos(std::move(Arg.FunctionInfos)),

967 Handles(std::move(Arg.Handles)) {

968

969 for (auto &H : Handles) {

971 H.GAR = this;

972 }

973}

974

976

981

982

983 Result.CollectSCCMembership(CG);

984

985

986 Result.AnalyzeGlobals(M);

987

988

989 Result.AnalyzeCallGraph(CG, M);

990

991 return Result;

992}

993

995

1001 };

1004}

1005

1010 G->NonAddressTakenGlobals.clear();

1011 G->UnknownFunctionsWithLocalLinkage = false;

1012 G->IndirectGlobals.clear();

1013 G->AllocsForIndirectGlobals.clear();

1014 G->FunctionInfos.clear();

1015 G->FunctionToSCCMap.clear();

1016 G->Handles.clear();

1017 G->CollectSCCMembership(CG);

1018 G->AnalyzeGlobals(M);

1019 G->AnalyzeCallGraph(CG, M);

1020 }

1022}

1023

1026 "Globals Alias Analysis", false, true)

1031

1034}

1035

1038}

1039

1042 return this->getAnalysis().getTLI(F);

1043 };

1045 M, GetTLI, getAnalysis().getCallGraph())));

1046 return false;

1047}

1048

1050 Result.reset();

1051 return false;

1052}

1053

1058}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Expand Atomic instructions

block Block Frequency Analysis

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...

static Function * getFunction(Constant *C)

static cl::opt< bool > EnableUnsafeGlobalsModRefAliasResults("enable-unsafe-globalsmodref-alias-results", cl::init(false), cl::Hidden)

static bool isNonEscapingGlobalNoAliasWithLoad(const GlobalValue *GV, const Value *V, int &Depth, const DataLayout &DL)

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

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

This header defines various interfaces for pass management in LLVM.

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...

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

This file defines the SmallPtrSet class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

The mod/ref information collected for a particular function.

FunctionInfo & operator=(FunctionInfo &&RHS)

void eraseModRefInfoForGlobal(const GlobalValue &GV)

Clear a global's ModRef info.

void setMayReadAnyGlobal()

Sets this function as potentially reading from any global.

void addModRefInfo(ModRefInfo NewMRI)

Adds new ModRefInfo for this function to its state.

void addFunctionInfo(const FunctionInfo &FI)

Add mod/ref info from another function into ours, saturating towards ModRef.

ModRefInfo getModRefInfo() const

Returns the ModRefInfo info for this function.

FunctionInfo()=default

Checks to document the invariants of the bit packing here.

FunctionInfo & operator=(const FunctionInfo &RHS)

void addModRefInfoForGlobal(const GlobalValue &GV, ModRefInfo NewMRI)

ModRefInfo globalClearMayReadAnyGlobal(int I) const

This method clears MayReadAnyGlobal bit added by GlobalsAAResult to return the corresponding ModRefIn...

bool mayReadAnyGlobal() const

Returns whether this function may read any global variable, and we don't know which global.

FunctionInfo(FunctionInfo &&Arg)

FunctionInfo(const FunctionInfo &Arg)

ModRefInfo getModRefInfoForGlobal(const GlobalValue &GV) const

Returns the ModRefInfo info for this function w.r.t.

This class stores info we want to provide to or retain within an alias query.

A base class to help implement the function alias analysis results concept.

The possible results of an alias query.

@ MayAlias

The two locations may or may not alias.

@ NoAlias

The two locations do not alias at all.

API to communicate dependencies between analyses during invalidation.

A container for analyses that lazily runs them and caches their results.

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

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

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

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

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

void setPreservesAll()

Set by analyses that do not transform their input at all.

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

An analysis pass to compute the CallGraph for a Module.

A node in the call graph for a module.

std::vector< CallRecord >::iterator iterator

The ModulePass which wraps up a CallGraph and the logic to build it.

The basic data container for the call graph of a Module of IR.

This is an important base class in LLVM.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

TypeSize getTypeAllocSize(Type *Ty) const

Returns the offset in bytes between successive objects of the specified type, including alignment pad...

const Function & getFunction() const

bool hasLocalLinkage() const

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

An alias analysis result set for globals.

ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)

bool invalidate(Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &)

static GlobalsAAResult analyzeModule(Module &M, std::function< const TargetLibraryInfo &(Function &F)> GetTLI, CallGraph &CG)

MemoryEffects getMemoryEffects(const Function *F)

getMemoryEffects - Return the behavior of the specified function if called from the specified call si...

AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI, const Instruction *CtxI)

alias - If one of the pointers is to a global that we are tracking, and the other is some random poin...

Legacy wrapper pass to provide the GlobalsAAResult object.

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

bool runOnModule(Module &M) override

runOnModule - Virtual method overriden by subclasses to process the module being operated on.

bool doFinalization(Module &M) override

doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...

Analysis pass providing a never-invalidated alias analysis result.

GlobalsAAResult run(Module &M, ModuleAnalysisManager &AM)

This instruction compares its operands according to the predicate given to the constructor.

An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...

A wrapper class for inspecting calls to intrinsic functions.

An instruction for reading from memory.

static MemoryEffectsBase unknown()

Create MemoryEffectsBase that can read and write any memory.

Representation for a specific memory location.

static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())

Return a location that may access any location before or after Ptr, while remaining within the underl...

const Value * Ptr

The address of the start of the location.

ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...

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

unsigned getOpcode() const

Return the opcode for this Instruction or ConstantExpr.

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

PointerIntPair - This class implements a pair of a pointer and small integer.

void setPointer(PointerTy PtrVal) &

void setInt(IntType IntVal) &

void setPointerAndInt(PointerTy PtrVal, IntType IntVal) &

PointerTy getPointer() const

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.

PreservedAnalysisChecker getChecker() const

Build a checker for this PreservedAnalyses and the specified analysis type.

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

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.

void push_back(const T &Elt)

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

An instruction for storing to memory.

Analysis pass providing the TargetLibraryInfo.

Provides information about what library functions are available for the current target.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const

Return true if it makes sense to take the size of this type.

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

LLVM Value Representation.

iterator_range< user_iterator > users()

const Value * stripPointerCastsForAliasAnalysis() const

Strip off pointer casts, all-zero GEPs, single-argument phi nodes and invariant group info.

Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.

@ C

The default llvm calling convention, compatible with C.

initializer< Ty > init(const Ty &Val)

const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get begin iterator over path.

This is an optimization pass for GlobalISel generic memory operations.

bool all_of(R &&range, UnaryPredicate P)

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

const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)

This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....

scc_iterator< T > scc_begin(const T &G)

Construct the begin iterator for a deduced graph type T.

bool isNoAliasCall(const Value *V)

Return true if this pointer is returned by a noalias function.

ModulePass * createGlobalsAAWrapperPass()

bool isModSet(const ModRefInfo MRI)

MemoryEffectsBase< IRMemLocation > MemoryEffects

Summary of how a function affects memory in the program.

bool isModOrRefSet(const ModRefInfo MRI)

ModRefInfo

Flags indicating whether a memory access modifies or references memory.

@ Ref

The access may reference the value stored in memory.

@ ModRef

The access may reference and may modify the value stored in memory.

@ Mod

The access may modify the value stored in memory.

@ NoModRef

The access neither references nor modifies the value stored in memory.

void initializeGlobalsAAWrapperPassPass(PassRegistry &)

Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)

If this if a call to a free function, return the freed operand.

bool isModAndRefSet(const ModRefInfo MRI)

OutputIt move(R &&Range, OutputIt Out)

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

void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=6)

This method is similar to getUnderlyingObject except that it can look through phi and select instruct...

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

Returns true if Element is found in Range.

bool isIdentifiedObject(const Value *V)

Return true if this pointer refers to a distinct and identifiable object.

Implement std::hash so that hash_code can be used in STL containers.

A special type used by analysis passes to provide an address that identifies that particular analysis...

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)