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);
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 () {
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();
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 (->getType()->isPointerTy())
325 return true;
326
327 for (Use &U : V->uses()) {
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 ( ||
->isDeclaration())
373 return true;
374
375
376
377
378 if (->hasFnAttr(Attribute::NoCallback) ||
379 ->isArgOperand(&U) ||
380 ->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 (->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(.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(.empty() && "SCC with no functions?");
501
503
504 if ( ||
->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 .isDeclaration() ||
.hasNoSync() ||
527 .hasFnAttribute(Attribute::NoCallback);
528 };
529
530
531
532 for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) {
533 if () {
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 (->onlyAccessesArgMemory() && MaySyncOrCallIntoModule(*F))
545
546
547 FI.setMayReadAnyGlobal();
548 } else {
550 if (->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 ((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)