LLVM  8.0.1
AliasAnalysisEvaluator.cpp
Go to the documentation of this file.
1 //===- AliasAnalysisEvaluator.cpp - Alias Analysis Accuracy Evaluator -----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "llvm/ADT/SetVector.h"
13 #include "llvm/IR/Constants.h"
14 #include "llvm/IR/DataLayout.h"
15 #include "llvm/IR/DerivedTypes.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/InstIterator.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/Pass.h"
22 #include "llvm/Support/Debug.h"
24 using namespace llvm;
25 
26 static cl::opt<bool> PrintAll("print-all-alias-modref-info", cl::ReallyHidden);
27 
28 static cl::opt<bool> PrintNoAlias("print-no-aliases", cl::ReallyHidden);
29 static cl::opt<bool> PrintMayAlias("print-may-aliases", cl::ReallyHidden);
30 static cl::opt<bool> PrintPartialAlias("print-partial-aliases", cl::ReallyHidden);
31 static cl::opt<bool> PrintMustAlias("print-must-aliases", cl::ReallyHidden);
32 
33 static cl::opt<bool> PrintNoModRef("print-no-modref", cl::ReallyHidden);
34 static cl::opt<bool> PrintRef("print-ref", cl::ReallyHidden);
35 static cl::opt<bool> PrintMod("print-mod", cl::ReallyHidden);
36 static cl::opt<bool> PrintModRef("print-modref", cl::ReallyHidden);
37 static cl::opt<bool> PrintMust("print-must", cl::ReallyHidden);
38 static cl::opt<bool> PrintMustRef("print-mustref", cl::ReallyHidden);
39 static cl::opt<bool> PrintMustMod("print-mustmod", cl::ReallyHidden);
40 static cl::opt<bool> PrintMustModRef("print-mustmodref", cl::ReallyHidden);
41 
42 static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden);
43 
44 static void PrintResults(AliasResult AR, bool P, const Value *V1,
45  const Value *V2, const Module *M) {
46  if (PrintAll || P) {
47  std::string o1, o2;
48  {
49  raw_string_ostream os1(o1), os2(o2);
50  V1->printAsOperand(os1, true, M);
51  V2->printAsOperand(os2, true, M);
52  }
53 
54  if (o2 < o1)
55  std::swap(o1, o2);
56  errs() << " " << AR << ":\t" << o1 << ", " << o2 << "\n";
57  }
58 }
59 
60 static inline void PrintModRefResults(const char *Msg, bool P, Instruction *I,
61  Value *Ptr, Module *M) {
62  if (PrintAll || P) {
63  errs() << " " << Msg << ": Ptr: ";
64  Ptr->printAsOperand(errs(), true, M);
65  errs() << "\t<->" << *I << '\n';
66  }
67 }
68 
69 static inline void PrintModRefResults(const char *Msg, bool P, CallBase *CallA,
70  CallBase *CallB, Module *M) {
71  if (PrintAll || P) {
72  errs() << " " << Msg << ": " << *CallA << " <-> " << *CallB << '\n';
73  }
74 }
75 
76 static inline void PrintLoadStoreResults(AliasResult AR, bool P,
77  const Value *V1, const Value *V2,
78  const Module *M) {
79  if (PrintAll || P) {
80  errs() << " " << AR << ": " << *V1 << " <-> " << *V2 << '\n';
81  }
82 }
83 
84 static inline bool isInterestingPointer(Value *V) {
85  return V->getType()->isPointerTy()
86  && !isa<ConstantPointerNull>(V);
87 }
88 
90  runInternal(F, AM.getResult<AAManager>(F));
91  return PreservedAnalyses::all();
92 }
93 
94 void AAEvaluator::runInternal(Function &F, AAResults &AA) {
95  const DataLayout &DL = F.getParent()->getDataLayout();
96 
97  ++FunctionCount;
98 
99  SetVector<Value *> Pointers;
101  SetVector<Value *> Loads;
102  SetVector<Value *> Stores;
103 
104  for (auto &I : F.args())
105  if (I.getType()->isPointerTy()) // Add all pointer arguments.
106  Pointers.insert(&I);
107 
108  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
109  if (I->getType()->isPointerTy()) // Add all pointer instructions.
110  Pointers.insert(&*I);
111  if (EvalAAMD && isa<LoadInst>(&*I))
112  Loads.insert(&*I);
113  if (EvalAAMD && isa<StoreInst>(&*I))
114  Stores.insert(&*I);
115  Instruction &Inst = *I;
116  if (auto *Call = dyn_cast<CallBase>(&Inst)) {
117  Value *Callee = Call->getCalledValue();
118  // Skip actual functions for direct function calls.
119  if (!isa<Function>(Callee) && isInterestingPointer(Callee))
120  Pointers.insert(Callee);
121  // Consider formals.
122  for (Use &DataOp : Call->data_ops())
123  if (isInterestingPointer(DataOp))
124  Pointers.insert(DataOp);
125  Calls.insert(Call);
126  } else {
127  // Consider all operands.
128  for (Instruction::op_iterator OI = Inst.op_begin(), OE = Inst.op_end();
129  OI != OE; ++OI)
130  if (isInterestingPointer(*OI))
131  Pointers.insert(*OI);
132  }
133  }
134 
137  errs() << "Function: " << F.getName() << ": " << Pointers.size()
138  << " pointers, " << Calls.size() << " call sites\n";
139 
140  // iterate over the worklist, and run the full (n^2)/2 disambiguations
141  for (SetVector<Value *>::iterator I1 = Pointers.begin(), E = Pointers.end();
142  I1 != E; ++I1) {
143  auto I1Size = LocationSize::unknown();
144  Type *I1ElTy = cast<PointerType>((*I1)->getType())->getElementType();
145  if (I1ElTy->isSized())
146  I1Size = LocationSize::precise(DL.getTypeStoreSize(I1ElTy));
147 
148  for (SetVector<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
149  auto I2Size = LocationSize::unknown();
150  Type *I2ElTy = cast<PointerType>((*I2)->getType())->getElementType();
151  if (I2ElTy->isSized())
152  I2Size = LocationSize::precise(DL.getTypeStoreSize(I2ElTy));
153 
154  AliasResult AR = AA.alias(*I1, I1Size, *I2, I2Size);
155  switch (AR) {
156  case NoAlias:
157  PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
158  ++NoAliasCount;
159  break;
160  case MayAlias:
161  PrintResults(AR, PrintMayAlias, *I1, *I2, F.getParent());
162  ++MayAliasCount;
163  break;
164  case PartialAlias:
165  PrintResults(AR, PrintPartialAlias, *I1, *I2, F.getParent());
166  ++PartialAliasCount;
167  break;
168  case MustAlias:
169  PrintResults(AR, PrintMustAlias, *I1, *I2, F.getParent());
170  ++MustAliasCount;
171  break;
172  }
173  }
174  }
175 
176  if (EvalAAMD) {
177  // iterate over all pairs of load, store
178  for (Value *Load : Loads) {
179  for (Value *Store : Stores) {
180  AliasResult AR = AA.alias(MemoryLocation::get(cast<LoadInst>(Load)),
181  MemoryLocation::get(cast<StoreInst>(Store)));
182  switch (AR) {
183  case NoAlias:
185  ++NoAliasCount;
186  break;
187  case MayAlias:
189  ++MayAliasCount;
190  break;
191  case PartialAlias:
193  ++PartialAliasCount;
194  break;
195  case MustAlias:
197  ++MustAliasCount;
198  break;
199  }
200  }
201  }
202 
203  // iterate over all pairs of store, store
204  for (SetVector<Value *>::iterator I1 = Stores.begin(), E = Stores.end();
205  I1 != E; ++I1) {
206  for (SetVector<Value *>::iterator I2 = Stores.begin(); I2 != I1; ++I2) {
207  AliasResult AR = AA.alias(MemoryLocation::get(cast<StoreInst>(*I1)),
208  MemoryLocation::get(cast<StoreInst>(*I2)));
209  switch (AR) {
210  case NoAlias:
211  PrintLoadStoreResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
212  ++NoAliasCount;
213  break;
214  case MayAlias:
215  PrintLoadStoreResults(AR, PrintMayAlias, *I1, *I2, F.getParent());
216  ++MayAliasCount;
217  break;
218  case PartialAlias:
220  ++PartialAliasCount;
221  break;
222  case MustAlias:
223  PrintLoadStoreResults(AR, PrintMustAlias, *I1, *I2, F.getParent());
224  ++MustAliasCount;
225  break;
226  }
227  }
228  }
229  }
230 
231  // Mod/ref alias analysis: compare all pairs of calls and values
232  for (CallBase *Call : Calls) {
233  for (auto Pointer : Pointers) {
234  auto Size = LocationSize::unknown();
235  Type *ElTy = cast<PointerType>(Pointer->getType())->getElementType();
236  if (ElTy->isSized())
238 
239  switch (AA.getModRefInfo(Call, Pointer, Size)) {
241  PrintModRefResults("NoModRef", PrintNoModRef, Call, Pointer,
242  F.getParent());
243  ++NoModRefCount;
244  break;
245  case ModRefInfo::Mod:
246  PrintModRefResults("Just Mod", PrintMod, Call, Pointer, F.getParent());
247  ++ModCount;
248  break;
249  case ModRefInfo::Ref:
250  PrintModRefResults("Just Ref", PrintRef, Call, Pointer, F.getParent());
251  ++RefCount;
252  break;
253  case ModRefInfo::ModRef:
254  PrintModRefResults("Both ModRef", PrintModRef, Call, Pointer,
255  F.getParent());
256  ++ModRefCount;
257  break;
258  case ModRefInfo::Must:
259  PrintModRefResults("Must", PrintMust, Call, Pointer, F.getParent());
260  ++MustCount;
261  break;
262  case ModRefInfo::MustMod:
263  PrintModRefResults("Just Mod (MustAlias)", PrintMustMod, Call, Pointer,
264  F.getParent());
265  ++MustModCount;
266  break;
267  case ModRefInfo::MustRef:
268  PrintModRefResults("Just Ref (MustAlias)", PrintMustRef, Call, Pointer,
269  F.getParent());
270  ++MustRefCount;
271  break;
273  PrintModRefResults("Both ModRef (MustAlias)", PrintMustModRef, Call,
274  Pointer, F.getParent());
275  ++MustModRefCount;
276  break;
277  }
278  }
279  }
280 
281  // Mod/ref alias analysis: compare all pairs of calls
282  for (CallBase *CallA : Calls) {
283  for (CallBase *CallB : Calls) {
284  if (CallA == CallB)
285  continue;
286  switch (AA.getModRefInfo(CallA, CallB)) {
288  PrintModRefResults("NoModRef", PrintNoModRef, CallA, CallB,
289  F.getParent());
290  ++NoModRefCount;
291  break;
292  case ModRefInfo::Mod:
293  PrintModRefResults("Just Mod", PrintMod, CallA, CallB, F.getParent());
294  ++ModCount;
295  break;
296  case ModRefInfo::Ref:
297  PrintModRefResults("Just Ref", PrintRef, CallA, CallB, F.getParent());
298  ++RefCount;
299  break;
300  case ModRefInfo::ModRef:
301  PrintModRefResults("Both ModRef", PrintModRef, CallA, CallB,
302  F.getParent());
303  ++ModRefCount;
304  break;
305  case ModRefInfo::Must:
306  PrintModRefResults("Must", PrintMust, CallA, CallB, F.getParent());
307  ++MustCount;
308  break;
309  case ModRefInfo::MustMod:
310  PrintModRefResults("Just Mod (MustAlias)", PrintMustMod, CallA, CallB,
311  F.getParent());
312  ++MustModCount;
313  break;
314  case ModRefInfo::MustRef:
315  PrintModRefResults("Just Ref (MustAlias)", PrintMustRef, CallA, CallB,
316  F.getParent());
317  ++MustRefCount;
318  break;
320  PrintModRefResults("Both ModRef (MustAlias)", PrintMustModRef, CallA,
321  CallB, F.getParent());
322  ++MustModRefCount;
323  break;
324  }
325  }
326  }
327 }
328 
329 static void PrintPercent(int64_t Num, int64_t Sum) {
330  errs() << "(" << Num * 100LL / Sum << "." << ((Num * 1000LL / Sum) % 10)
331  << "%)\n";
332 }
333 
335  if (FunctionCount == 0)
336  return;
337 
338  int64_t AliasSum =
339  NoAliasCount + MayAliasCount + PartialAliasCount + MustAliasCount;
340  errs() << "===== Alias Analysis Evaluator Report =====\n";
341  if (AliasSum == 0) {
342  errs() << " Alias Analysis Evaluator Summary: No pointers!\n";
343  } else {
344  errs() << " " << AliasSum << " Total Alias Queries Performed\n";
345  errs() << " " << NoAliasCount << " no alias responses ";
346  PrintPercent(NoAliasCount, AliasSum);
347  errs() << " " << MayAliasCount << " may alias responses ";
348  PrintPercent(MayAliasCount, AliasSum);
349  errs() << " " << PartialAliasCount << " partial alias responses ";
350  PrintPercent(PartialAliasCount, AliasSum);
351  errs() << " " << MustAliasCount << " must alias responses ";
352  PrintPercent(MustAliasCount, AliasSum);
353  errs() << " Alias Analysis Evaluator Pointer Alias Summary: "
354  << NoAliasCount * 100 / AliasSum << "%/"
355  << MayAliasCount * 100 / AliasSum << "%/"
356  << PartialAliasCount * 100 / AliasSum << "%/"
357  << MustAliasCount * 100 / AliasSum << "%\n";
358  }
359 
360  // Display the summary for mod/ref analysis
361  int64_t ModRefSum = NoModRefCount + RefCount + ModCount + ModRefCount +
362  MustCount + MustRefCount + MustModCount + MustModRefCount;
363  if (ModRefSum == 0) {
364  errs() << " Alias Analysis Mod/Ref Evaluator Summary: no "
365  "mod/ref!\n";
366  } else {
367  errs() << " " << ModRefSum << " Total ModRef Queries Performed\n";
368  errs() << " " << NoModRefCount << " no mod/ref responses ";
369  PrintPercent(NoModRefCount, ModRefSum);
370  errs() << " " << ModCount << " mod responses ";
371  PrintPercent(ModCount, ModRefSum);
372  errs() << " " << RefCount << " ref responses ";
373  PrintPercent(RefCount, ModRefSum);
374  errs() << " " << ModRefCount << " mod & ref responses ";
375  PrintPercent(ModRefCount, ModRefSum);
376  errs() << " " << MustCount << " must responses ";
377  PrintPercent(MustCount, ModRefSum);
378  errs() << " " << MustModCount << " must mod responses ";
379  PrintPercent(MustModCount, ModRefSum);
380  errs() << " " << MustRefCount << " must ref responses ";
381  PrintPercent(MustRefCount, ModRefSum);
382  errs() << " " << MustModRefCount << " must mod & ref responses ";
383  PrintPercent(MustModRefCount, ModRefSum);
384  errs() << " Alias Analysis Evaluator Mod/Ref Summary: "
385  << NoModRefCount * 100 / ModRefSum << "%/"
386  << ModCount * 100 / ModRefSum << "%/" << RefCount * 100 / ModRefSum
387  << "%/" << ModRefCount * 100 / ModRefSum << "%/"
388  << MustCount * 100 / ModRefSum << "%/"
389  << MustRefCount * 100 / ModRefSum << "%/"
390  << MustModCount * 100 / ModRefSum << "%/"
391  << MustModRefCount * 100 / ModRefSum << "%\n";
392  }
393 }
394 
395 namespace llvm {
397  std::unique_ptr<AAEvaluator> P;
398 
399 public:
400  static char ID; // Pass identification, replacement for typeid
403  }
404 
405  void getAnalysisUsage(AnalysisUsage &AU) const override {
407  AU.setPreservesAll();
408  }
409 
410  bool doInitialization(Module &M) override {
411  P.reset(new AAEvaluator());
412  return false;
413  }
414 
415  bool runOnFunction(Function &F) override {
416  P->runInternal(F, getAnalysis<AAResultsWrapperPass>().getAAResults());
417  return false;
418  }
419  bool doFinalization(Module &M) override {
420  P.reset();
421  return false;
422  }
423 };
424 }
425 
426 char AAEvalLegacyPass::ID = 0;
428  "Exhaustive Alias Analysis Precision Evaluator", false,
429  true)
432  "Exhaustive Alias Analysis Precision Evaluator", false,
433  true)
434 
The access may reference and may modify the value stored in memory.
static cl::opt< bool > PrintPartialAlias("print-partial-aliases", cl::ReallyHidden)
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
The access neither references nor modifies the value stored in memory.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:770
This class represents lattice values for constants.
Definition: AllocatorList.h:24
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:78
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:265
static constexpr LocationSize unknown()
void initializeAAEvalLegacyPassPass(PassRegistry &)
This file implements a simple N^2 alias analysis accuracy evaluator.
static void PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr, Module *M)
static cl::opt< bool > PrintMod("print-mod", cl::ReallyHidden)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
The two locations do not alias at all.
Definition: AliasAnalysis.h:84
static LocationSize precise(uint64_t Value)
static cl::opt< bool > PrintModRef("print-modref", cl::ReallyHidden)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1014
FunctionPass * createAAEvalPass()
Create a wrapper of the above for the legacy pass manager.
F(f)
block Block Frequency true
iterator end()
Get an iterator to the end of the SetVector.
Definition: SetVector.h:93
op_iterator op_begin()
Definition: User.h:230
static cl::opt< bool > PrintMustAlias("print-must-aliases", cl::ReallyHidden)
static void PrintResults(AliasResult AR, bool P, const Value *V1, const Value *V2, const Module *M)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:51
inst_iterator inst_begin(Function *F)
Definition: InstIterator.h:132
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:371
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
Must is provided for completeness, but no routines will return only Must today.
The access may reference the value stored in memory, a mustAlias relation was found, and no mayAlias or partialAlias found.
The access may reference the value stored in memory.
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:142
The access may reference, modify or both the value stored in memory, a mustAlias relation was found...
The access may modify the value stored in memory, a mustAlias relation was found, and no mayAlias or ...
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:83
INITIALIZE_PASS_BEGIN(AAEvalLegacyPass, "aa-eval", "Exhaustive Alias Analysis Precision Evaluator", false, true) INITIALIZE_PASS_END(AAEvalLegacyPass
static bool isInterestingPointer(Value *V)
amdgpu Simplify well known AMD library false Value * Callee
AliasResult
The possible results of an alias query.
Definition: AliasAnalysis.h:78
static cl::opt< bool > PrintRef("print-ref", cl::ReallyHidden)
#define P(N)
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< bool > PrintMayAlias("print-may-aliases", cl::ReallyHidden)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:224
A manager for alias analyses.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
Represent the analysis usage information of a pass.
op_iterator op_end()
Definition: User.h:232
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:160
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
Definition: AsmWriter.cpp:4225
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
The two locations may or may not alias. This is the least precise result.
Definition: AliasAnalysis.h:86
This class evaluates LLVM IR, producing the Constant representing each SSA instruction.
Definition: Evaluator.h:39
The two locations precisely alias each other.
Definition: AliasAnalysis.h:90
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:298
Module.h This file contains the declarations for the Module class.
The access may modify the value stored in memory.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:941
void setPreservesAll()
Set by analyses that do not transform their input at all.
static cl::opt< bool > PrintMust("print-must", cl::ReallyHidden)
static cl::opt< bool > PrintMustMod("print-mustmod", cl::ReallyHidden)
static void PrintPercent(int64_t Num, int64_t Sum)
static void PrintLoadStoreResults(AliasResult AR, bool P, const Value *V1, const Value *V2, const Module *M)
block Block Frequency Analysis
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
static cl::opt< bool > EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden)
#define I(x, y, z)
Definition: MD5.cpp:58
uint32_t Size
Definition: Profile.cpp:47
static cl::opt< bool > PrintNoModRef("print-no-modref", cl::ReallyHidden)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:566
LLVM Value Representation.
Definition: Value.h:73
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Definition: DataLayout.h:419
static cl::opt< bool > PrintMustRef("print-mustref", cl::ReallyHidden)
inst_iterator inst_end(Function *F)
Definition: InstIterator.h:133
A container for analyses that lazily runs them and caches their results.
static cl::opt< bool > PrintAll("print-all-alias-modref-info", cl::ReallyHidden)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
The two locations alias, but only due to a partial overlap.
Definition: AliasAnalysis.h:88
static cl::opt< bool > PrintNoAlias("print-no-aliases", cl::ReallyHidden)
static cl::opt< bool > PrintMustModRef("print-mustmodref", cl::ReallyHidden)
iterator_range< arg_iterator > args()
Definition: Function.h:689
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...