Go to the documentation of this file.
35 #define DEBUG_TYPE "globalsmodref-aa"
38 "Number of global vars without address taken");
39 STATISTIC(NumNonAddrTakenFunctions,
"Number of functions without address taken");
40 STATISTIC(NumNoMemFunctions,
"Number of functions that do not access memory");
41 STATISTIC(NumReadMemFunctions,
"Number of functions that only read memory");
42 STATISTIC(NumIndirectGlobalVars,
"Number of indirect global objects");
70 struct alignas(8) AlignedMap {
71 AlignedMap() =
default;
72 AlignedMap(
const AlignedMap &
Arg) =
default;
77 struct AlignedMapPointerTraits {
78 static inline void *getAsVoidPointer(AlignedMap *
P) {
return P; }
79 static inline AlignedMap *getFromVoidPointer(
void *
P) {
80 return (AlignedMap *)
P;
82 static constexpr
int NumLowBitsAvailable = 3;
83 static_assert(
alignof(AlignedMap) >= (1 << NumLowBitsAvailable),
84 "AlignedMap insufficiently aligned to have enough low bits.");
93 enum { MayReadAnyGlobal = 4 };
98 "ModRef and the MayReadAnyGlobal flag bits overlap.");
99 static_assert(((MayReadAnyGlobal |
101 AlignedMapPointerTraits::NumLowBitsAvailable) == 0,
102 "Insufficient low bits to store our flag and ModRef info.");
107 delete Info.getPointer();
114 if (
const auto *ArgPtr =
Arg.Info.getPointer())
115 Info.setPointer(
new AlignedMap(*ArgPtr));
119 Arg.Info.setPointerAndInt(
nullptr, 0);
122 delete Info.getPointer();
123 Info.setPointerAndInt(
nullptr,
RHS.Info.getInt());
124 if (
const auto *RHSPtr =
RHS.Info.getPointer())
125 Info.setPointer(
new AlignedMap(*RHSPtr));
129 delete Info.getPointer();
130 Info.setPointerAndInt(
RHS.Info.getPointer(),
RHS.Info.getInt());
131 RHS.Info.setPointerAndInt(
nullptr, 0);
165 if (AlignedMap *
P =
Info.getPointer()) {
166 auto I =
P->Map.find(&GV);
167 if (
I !=
P->Map.end())
182 for (
const auto &
G :
P->Map)
187 AlignedMap *
P =
Info.getPointer();
189 P =
new AlignedMap();
192 auto &GlobalMRI =
P->Map[&GV];
199 if (AlignedMap *
P =
Info.getPointer())
212 void GlobalsAAResult::DeletionCallbackHandle::deleted() {
213 Value *V = getValPtr();
214 if (
auto *
F = dyn_cast<Function>(V))
215 GAR->FunctionInfos.erase(
F);
218 if (GAR->NonAddressTakenGlobals.erase(GV)) {
221 if (GAR->IndirectGlobals.erase(GV)) {
223 for (
auto I = GAR->AllocsForIndirectGlobals.begin(),
224 E = GAR->AllocsForIndirectGlobals.end();
227 GAR->AllocsForIndirectGlobals.erase(
I);
232 for (
auto &FIPair : GAR->FunctionInfos)
233 FIPair.second.eraseModRefInfoForGlobal(*GV);
238 GAR->AllocsForIndirectGlobals.erase(V);
242 GAR->Handles.erase(
I);
252 else if (!
isModSet(FI->getModRefInfo()))
263 if (!Call->hasOperandBundles())
264 if (
const Function *
F = Call->getCalledFunction())
268 else if (!
isModSet(FI->getModRefInfo()))
278 GlobalsAAResult::getFunctionInfo(
const Function *
F) {
279 auto I = FunctionInfos.find(
F);
280 if (
I != FunctionInfos.end())
289 void GlobalsAAResult::AnalyzeGlobals(
Module &M) {
292 if (
F.hasLocalLinkage()) {
293 if (!AnalyzeUsesOfPointer(&
F)) {
295 NonAddressTakenGlobals.insert(&
F);
297 Handles.emplace_front(*
this, &
F);
298 Handles.front().I = Handles.begin();
299 ++NumNonAddrTakenFunctions;
301 UnknownFunctionsWithLocalLinkage =
true;
306 if (GV.hasLocalLinkage()) {
307 if (!AnalyzeUsesOfPointer(&GV, &Readers,
308 GV.isConstant() ?
nullptr : &Writers)) {
310 NonAddressTakenGlobals.insert(&GV);
311 Handles.emplace_front(*
this, &GV);
312 Handles.front().I = Handles.begin();
315 if (TrackedFunctions.
insert(Reader).second) {
316 Handles.emplace_front(*
this, Reader);
317 Handles.front().I = Handles.begin();
322 if (!GV.isConstant())
324 if (TrackedFunctions.
insert(Writer).second) {
325 Handles.emplace_front(*
this, Writer);
326 Handles.front().I = Handles.begin();
330 ++NumNonAddrTakenGlobalVars;
333 if (GV.getValueType()->isPointerTy() &&
334 AnalyzeIndirectGlobalMemory(&GV))
335 ++NumIndirectGlobalVars;
348 bool GlobalsAAResult::AnalyzeUsesOfPointer(
Value *V,
356 User *
I = U.getUser();
357 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
359 Readers->
insert(LI->getParent()->getParent());
361 if (V ==
SI->getOperand(1)) {
363 Writers->
insert(
SI->getParent()->getParent());
364 }
else if (
SI->getOperand(1) != OkayStoreDest) {
368 if (AnalyzeUsesOfPointer(
I, Readers, Writers))
372 if (AnalyzeUsesOfPointer(
I, Readers, Writers, OkayStoreDest))
374 }
else if (
auto *Call = dyn_cast<CallBase>(
I)) {
377 if (
Call->isDataOperand(&U)) {
379 if (
Call->isArgOperand(&U) &&
382 Writers->
insert(
Call->getParent()->getParent());
387 }
else if (
ICmpInst *ICI = dyn_cast<ICmpInst>(
I)) {
388 if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
390 }
else if (
Constant *
C = dyn_cast<Constant>(
I)) {
392 if (isa<GlobalValue>(
C) ||
C->isConstantUsed())
409 bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(
GlobalVariable *GV) {
412 std::vector<Value *> AllocRelatedValues;
416 if (!
C->isNullValue())
422 if (
LoadInst *LI = dyn_cast<LoadInst>(U)) {
426 if (AnalyzeUsesOfPointer(LI))
429 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(U)) {
431 if (
SI->getOperand(0) == GV)
435 if (isa<ConstantPointerNull>(
SI->getOperand(0)))
446 if (AnalyzeUsesOfPointer(Ptr,
nullptr,
nullptr,
451 AllocRelatedValues.push_back(Ptr);
460 while (!AllocRelatedValues.empty()) {
461 AllocsForIndirectGlobals[AllocRelatedValues.back()] = GV;
462 Handles.emplace_front(*
this, AllocRelatedValues.back());
463 Handles.front().I = Handles.begin();
464 AllocRelatedValues.pop_back();
466 IndirectGlobals.insert(GV);
467 Handles.emplace_front(*
this, GV);
468 Handles.front().I = Handles.begin();
472 void GlobalsAAResult::CollectSCCMembership(
CallGraph &CG) {
477 const std::vector<CallGraphNode *> &
SCC = *
I;
478 assert(!
SCC.empty() &&
"SCC with no functions?");
480 for (
auto *CGN :
SCC)
482 FunctionToSCCMap[
F] = SCCID;
495 const std::vector<CallGraphNode *> &
SCC = *
I;
496 assert(!
SCC.empty() &&
"SCC with no functions?");
500 if (!
F || !
F->isDefinitionExact()) {
504 for (
auto *Node :
SCC)
505 FunctionInfos.erase(Node->getFunction());
509 FunctionInfo &FI = FunctionInfos[
F];
510 Handles.emplace_front(*
this,
F);
511 Handles.front().I = Handles.begin();
512 bool KnowNothing =
false;
521 auto MaySyncOrCallIntoModule = [](
const Function &
F) {
522 return !
F.isDeclaration() || !
F.hasNoSync() ||
523 !
F.hasFnAttribute(Attribute::NoCallback);
528 for (
unsigned i = 0,
e =
SCC.size();
i !=
e && !KnowNothing; ++
i) {
534 if (
F->isDeclaration() ||
F->hasOptNone()) {
536 if (
F->doesNotAccessMemory()) {
538 }
else if (
F->onlyReadsMemory()) {
540 if (!
F->onlyAccessesArgMemory() && MaySyncOrCallIntoModule(*
F))
543 FI.setMayReadAnyGlobal();
546 if (!
F->onlyAccessesArgMemory())
547 FI.setMayReadAnyGlobal();
548 if (MaySyncOrCallIntoModule(*
F)) {
557 CI !=
E && !KnowNothing; ++CI)
559 if (FunctionInfo *CalleeFI = getFunctionInfo(Callee)) {
561 FI.addFunctionInfo(*CalleeFI);
577 for (
auto *Node :
SCC)
578 FunctionInfos.erase(Node->getFunction());
583 for (
auto *Node :
SCC) {
590 if (Node->getFunction()->hasOptNone())
599 if (
auto *Call = dyn_cast<CallBase>(&
I)) {
600 auto &TLI = GetTLI(*Node->getFunction());
605 }
else if (
Function *Callee =
Call->getCalledFunction()) {
607 if (
Callee->isIntrinsic()) {
608 if (isa<DbgInfoIntrinsic>(Call))
622 if (
I.mayReadFromMemory())
624 if (
I.mayWriteToMemory())
630 ++NumReadMemFunctions;
638 FunctionInfo CachedFI = FI;
639 for (
unsigned i = 1,
e =
SCC.size();
i !=
e; ++
i)
640 FunctionInfos[
SCC[
i]->getFunction()] = CachedFI;
658 if (isa<GlobalValue>(Input) || isa<Argument>(Input) || isa<CallInst>(Input) ||
659 isa<InvokeInst>(Input))
675 if (
auto *LI = dyn_cast<LoadInst>(Input)) {
679 if (
auto *
SI = dyn_cast<SelectInst>(Input)) {
683 Inputs.push_back(
LHS);
685 Inputs.push_back(
RHS);
688 if (
auto *PN = dyn_cast<PHINode>(Input)) {
689 for (
const Value *
Op : PN->incoming_values()) {
692 Inputs.push_back(
Op);
698 }
while (!Inputs.empty());
729 bool GlobalsAAResult::isNonEscapingGlobalNoAlias(
const GlobalValue *GV,
745 if (
auto *InputGV = dyn_cast<GlobalValue>(Input)) {
753 auto *GVar = dyn_cast<GlobalVariable>(GV);
754 auto *InputGVar = dyn_cast<GlobalVariable>(InputGV);
755 if (GVar && InputGVar &&
756 !GVar->isDeclaration() && !InputGVar->isDeclaration() &&
757 !GVar->isInterposable() && !InputGVar->isInterposable()) {
758 Type *GVType = GVar->getInitializer()->getType();
759 Type *InputGVType = InputGVar->getInitializer()->getType();
771 if (isa<Argument>(Input) || isa<CallInst>(Input) ||
772 isa<InvokeInst>(Input)) {
786 if (
auto *LI = dyn_cast<LoadInst>(Input)) {
796 if (
auto *
SI = dyn_cast<SelectInst>(Input)) {
800 Inputs.push_back(
LHS);
802 Inputs.push_back(
RHS);
805 if (
auto *PN = dyn_cast<PHINode>(Input)) {
806 for (
const Value *
Op : PN->incoming_values()) {
809 Inputs.push_back(
Op);
821 }
while (!Inputs.empty());
832 return !PAC.preservedWhenStateless();
849 const GlobalValue *GV1 = dyn_cast<GlobalValue>(UV1);
850 const GlobalValue *GV2 = dyn_cast<GlobalValue>(UV2);
854 if (GV1 && !NonAddressTakenGlobals.count(GV1))
856 if (GV2 && !NonAddressTakenGlobals.count(GV2))
861 if (GV1 && GV2 && GV1 != GV2)
868 if ((GV1 || GV2) && GV1 != GV2)
873 if ((GV1 || GV2) && GV1 != GV2) {
875 const Value *UV = GV1 ? UV2 : UV1;
876 if (isNonEscapingGlobalNoAlias(GV, UV))
888 if (
const LoadInst *LI = dyn_cast<LoadInst>(UV1))
889 if (
GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
890 if (IndirectGlobals.count(GV))
892 if (
const LoadInst *LI = dyn_cast<LoadInst>(UV2))
893 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
894 if (IndirectGlobals.count(GV))
900 GV1 = AllocsForIndirectGlobals.lookup(UV1);
902 GV2 = AllocsForIndirectGlobals.lookup(UV2);
907 if (GV1 && GV2 && GV1 != GV2)
914 if ((GV1 || GV2) && GV1 != GV2)
923 if (Call->doesNotAccessMemory())
930 for (
auto &A : Call->args()) {
942 return ConservativeResult;
945 return ConservativeResult;
964 if (
const Function *
F = Call->getCalledFunction())
965 if (NonAddressTakenGlobals.count(GV))
967 Known =
unionModRef(FI->getModRefInfoForGlobal(*GV),
968 getModRefInfoForArgument(Call, GV, AAQI));
975 GlobalsAAResult::GlobalsAAResult(
982 NonAddressTakenGlobals(
std::
move(
Arg.NonAddressTakenGlobals)),
983 IndirectGlobals(
std::
move(
Arg.IndirectGlobals)),
984 AllocsForIndirectGlobals(
std::
move(
Arg.AllocsForIndirectGlobals)),
988 for (
auto &
H : Handles) {
1002 Result.CollectSCCMembership(CG);
1005 Result.AnalyzeGlobals(
M);
1008 Result.AnalyzeCallGraph(CG,
M);
1029 G->NonAddressTakenGlobals.clear();
1030 G->UnknownFunctionsWithLocalLinkage =
false;
1031 G->IndirectGlobals.clear();
1032 G->AllocsForIndirectGlobals.clear();
1033 G->FunctionInfos.clear();
1034 G->FunctionToSCCMap.clear();
1036 G->CollectSCCMembership(CG);
1037 G->AnalyzeGlobals(
M);
1038 G->AnalyzeCallGraph(CG,
M);
1045 "Globals Alias Analysis",
false,
true)
1061 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1064 M, GetTLI, getAnalysis<CallGraphWrapperPass>().getCallGraph())));
Analysis pass providing a never-invalidated alias analysis result.
A set of analyses that are preserved following a run of a transformation pass.
An alias analysis result set for globals.
@ NoModRef
The access neither references nor modifies the value stored in memory.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
std::vector< CallRecord >::iterator iterator
A parsed version of the target data layout string in and methods for querying it.
LLVM_NODISCARD bool isModAndRefSet(const ModRefInfo MRI)
static GlobalsAAResult analyzeModule(Module &M, std::function< const TargetLibraryInfo &(Function &F)> GetTLI, CallGraph &CG)
An analysis pass to compute the CallGraph for a Module.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
LLVM_NODISCARD bool isModOrRefSet(const ModRefInfo MRI)
bool isPointerTy() const
True if this is an instance of PointerType.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const Value * Ptr
The address of the start of the location.
FunctionInfo(const FunctionInfo &Arg)
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_NODISCARD ModRefInfo createModRefInfo(const FunctionModRefBehavior FMRB)
The basic data container for the call graph of a Module of IR.
FunctionAnalysisManager FAM
void addFunctionInfo(const FunctionInfo &FI)
Add mod/ref info from another function into ours, saturating towards ModRef.
The instances of the Type class are immutable: once they are created, they are never changed.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
The possible results of an alias query.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
LLVM_NODISCARD T pop_back_val()
static Error getInt(StringRef R, IntTy &Result)
Get an unsigned integer, including error checks.
@ FMRB_UnknownModRefBehavior
This indicates that the function could not be classified into one of the behaviors above.
FunctionInfo & operator=(FunctionInfo &&RHS)
static bool isNonEscapingGlobalNoAliasWithLoad(const GlobalValue *GV, const Value *V, int &Depth, const DataLayout &DL)
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This class stores info we want to provide to or retain within an alias query.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
INITIALIZE_PASS_BEGIN(GlobalsAAWrapperPass, "globals-aa", "Globals Alias Analysis", false, true) INITIALIZE_PASS_END(GlobalsAAWrapperPass
FunctionModRefBehavior getModRefBehavior(const Function *F)
getModRefBehavior - Return the behavior of the specified function if called from the specified call s...
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
@ Ref
The access may reference the value stored in memory.
bool invalidate(Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
@ MustModRef
The access may reference, modify or both the value stored in memory, a mustAlias relation was found,...
void addModRefInfoForGlobal(const GlobalValue &GV, ModRefInfo NewMRI)
(vector float) vec_cmpeq(*A, *B) C
Represent the analysis usage information of a pass.
void initializeGlobalsAAWrapperPassPass(PassRegistry &)
iterator_range< use_iterator > uses()
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
STATISTIC(NumFunctions, "Total number of functions")
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
A node in the call graph for a module.
Analysis containing CSE Info
API to communicate dependencies between analyses during invalidation.
LLVM_NODISCARD bool isModSet(const ModRefInfo MRI)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI)
ModulePass * createGlobalsAAWrapperPass()
PointerTy getPointer() const
inst_range instructions(Function *F)
An instruction for storing to memory.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
ModRefInfo globalClearMayReadAnyGlobal(int I) const
This method clears MayReadAnyGlobal bit added by GlobalsAAResult to return the corresponding ModRefIn...
This is an important base class in LLVM.
void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, LoopInfo *LI=nullptr, unsigned MaxLookup=6)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
ModRefInfo getModRefInfo() const
Returns the ModRefInfo info for this function.
The mod/ref information collected for a particular function.
This instruction compares its operands according to the predicate given to the constructor.
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
bool mayReadAnyGlobal() const
Returns whether this function may read any global variable, and we don't know which global.
A special type used by analysis passes to provide an address that identifies that particular analysis...
The ModulePass which wraps up a CallGraph and the logic to build it.
FunctionInfo & operator=(const FunctionInfo &RHS)
initializer< Ty > init(const Ty &Val)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
LLVM_NODISCARD ModRefInfo unionModRef(const ModRefInfo MRI1, const ModRefInfo MRI2)
ModRefInfo getModRefInfoForGlobal(const GlobalValue &GV) const
Returns the ModRefInfo info for this function w.r.t.
FunctionInfo(FunctionInfo &&Arg)
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void addModRefInfo(ModRefInfo NewMRI)
Adds new ModRefInfo for this function to its state.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
StandardInstrumentations SI(Debug, VerifyEach)
bool hasLocalLinkage() const
const Value * stripPointerCastsForAliasAnalysis() const
Strip off pointer casts, all-zero GEPs, single-argument phi nodes and invariant group info.
print Print MemDeps of function
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
A Module instance is used to store all the information related to an LLVM module.
@ FMRB_DoesNotAccessMemory
This function does not perform any non-local loads or stores to memory.
FunctionModRefBehavior getModRefBehavior(const CallBase *Call)
const Function & getFunction() const
Type * getType() const
All values are typed, get the type of this value.
@ FMRB_OnlyReadsMemory
This function does not perform any non-local stores or volatile loads, but may read from any memory l...
@ NoAlias
The two locations do not alias at all.
@ Mod
The access may modify the value stored in memory.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
FunctionModRefBehavior
Summary of how a function affects memory in the program.
An instruction for reading from memory.
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
amdgpu Simplify well known AMD library false FunctionCallee Callee
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI)
alias - If one of the pointers is to a global that we are tracking, and the other is some random poin...
GlobalsAAResult run(Module &M, ModuleAnalysisManager &AM)
bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
void setMayReadAnyGlobal()
Sets this function as potentially reading from any global.
void setPreservesAll()
Set by analyses that do not transform their input at all.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static cl::opt< bool > EnableUnsafeGlobalsModRefAliasResults("enable-unsafe-globalsmodref-alias-results", cl::init(false), cl::Hidden)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
void eraseModRefInfoForGlobal(const GlobalValue &GV)
Clear a global's ModRef info.
Provides information about what library functions are available for the current target.
FunctionInfo()=default
Checks to document the invariants of the bit packing here.
Legacy wrapper pass to provide the GlobalsAAResult object.
LLVM_NODISCARD ModRefInfo setMust(const ModRefInfo MRI)
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...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
A container for analyses that lazily runs them and caches their results.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
AnalysisUsage & addRequired()
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
LLVM_NODISCARD ModRefInfo intersectModRef(const ModRefInfo MRI1, const ModRefInfo MRI2)
LLVM Value Representation.
Analysis pass providing the TargetLibraryInfo.
iterator_range< user_iterator > users()
A CRTP-driven "mixin" base class to help implement the function alias analysis results concept.
@ ModRef
The access may reference and may modify the value stored in memory.
Representation for a specific memory location.
const CallInst * isFreeCall(const Value *I, const TargetLibraryInfo *TLI)
isFreeCall - Returns non-null if the value is a call to the builtin free()
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...