1 //===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the AliasSetTracker and AliasSet classes.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Analysis/AliasSetTracker.h"
14 #include "llvm/Analysis/AliasAnalysis.h"
15 #include "llvm/Analysis/GuardUtils.h"
16 #include "llvm/Analysis/MemoryLocation.h"
17 #include "llvm/Config/llvm-config.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/IR/InstIterator.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/IntrinsicInst.h"
22 #include "llvm/IR/PassManager.h"
23 #include "llvm/IR/PatternMatch.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/InitializePasses.h"
26 #include "llvm/Pass.h"
27 #include "llvm/Support/AtomicOrdering.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
33
34 using namespace llvm;
35
36 static cl::opt<unsigned>
37 SaturationThreshold("alias-set-saturation-threshold", cl::Hidden,
38 cl::init(250),
39 cl::desc("The maximum number of pointers may-alias "
40 "sets may contain before degradation"));
41
42 /// mergeSetIn - Merge the specified alias set into this alias set.
mergeSetIn(AliasSet & AS,AliasSetTracker & AST,BatchAAResults & BatchAA)43 void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
44 BatchAAResults &BatchAA) {
45 assert(!AS.Forward && "Alias set is already forwarding!");
46 assert(!Forward && "This set is a forwarding set!!");
47
48 bool WasMustAlias = (Alias == SetMustAlias);
49 // Update the alias and access types of this set...
50 Access |= AS.Access;
51 Alias |= AS.Alias;
52
53 if (Alias == SetMustAlias) {
54 // Check that these two merged sets really are must aliases. Since both
55 // used to be must-alias sets, we can just check any pointer from each set
56 // for aliasing.
57 PointerRec *L = getSomePointer();
58 PointerRec *R = AS.getSomePointer();
59
60 // If the pointers are not a must-alias pair, this set becomes a may alias.
61 if (!BatchAA.isMustAlias(
62 MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()),
63 MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())))
64 Alias = SetMayAlias;
65 }
66
67 if (Alias == SetMayAlias) {
68 if (WasMustAlias)
69 AST.TotalMayAliasSetSize += size();
70 if (AS.Alias == SetMustAlias)
71 AST.TotalMayAliasSetSize += AS.size();
72 }
73
74 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
75 if (UnknownInsts.empty()) { // Merge call sites...
76 if (ASHadUnknownInsts) {
77 std::swap(UnknownInsts, AS.UnknownInsts);
78 addRef();
79 }
80 } else if (ASHadUnknownInsts) {
81 llvm::append_range(UnknownInsts, AS.UnknownInsts);
82 AS.UnknownInsts.clear();
83 }
84
85 AS.Forward = this; // Forward across AS now...
86 addRef(); // AS is now pointing to us...
87
88 // Merge the list of constituent pointers...
89 if (AS.PtrList) {
90 SetSize += AS.size();
91 AS.SetSize = 0;
92 *PtrListEnd = AS.PtrList;
93 AS.PtrList->setPrevInList(PtrListEnd);
94 PtrListEnd = AS.PtrListEnd;
95
96 AS.PtrList = nullptr;
97 AS.PtrListEnd = &AS.PtrList;
98 assert(*AS.PtrListEnd == nullptr && "End of list is not null?");
99 }
100 if (ASHadUnknownInsts)
101 AS.dropRef(AST);
102 }
103
removeAliasSet(AliasSet * AS)104 void AliasSetTracker::removeAliasSet(AliasSet *AS) {
105 if (AliasSet *Fwd = AS->Forward) {
106 Fwd->dropRef(*this);
107 AS->Forward = nullptr;
108 } else // Update TotalMayAliasSetSize only if not forwarding.
109 if (AS->Alias == AliasSet::SetMayAlias)
110 TotalMayAliasSetSize -= AS->size();
111
112 AliasSets.erase(AS);
113 // If we've removed the saturated alias set, set saturated marker back to
114 // nullptr and ensure this tracker is empty.
115 if (AS == AliasAnyAS) {
116 AliasAnyAS = nullptr;
117 assert(AliasSets.empty() && "Tracker not empty");
118 }
119 }
120
removeFromTracker(AliasSetTracker & AST)121 void AliasSet::removeFromTracker(AliasSetTracker &AST) {
122 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
123 AST.removeAliasSet(this);
124 }
125
addPointer(AliasSetTracker & AST,PointerRec & Entry,LocationSize Size,const AAMDNodes & AAInfo,bool KnownMustAlias,bool SkipSizeUpdate)126 void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,
127 LocationSize Size, const AAMDNodes &AAInfo,
128 bool KnownMustAlias, bool SkipSizeUpdate) {
129 assert(!Entry.hasAliasSet() && "Entry already in set!");
130
131 // Check to see if we have to downgrade to _may_ alias.
132 if (isMustAlias())
133 if (PointerRec *P = getSomePointer()) {
134 if (!KnownMustAlias) {
135 BatchAAResults &AA = AST.getAliasAnalysis();
136 AliasResult Result = AA.alias(
137 MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()),
138 MemoryLocation(Entry.getValue(), Size, AAInfo));
139 if (Result != AliasResult::MustAlias) {
140 Alias = SetMayAlias;
141 AST.TotalMayAliasSetSize += size();
142 }
143 assert(Result != AliasResult::NoAlias && "Cannot be part of must set!");
144 } else if (!SkipSizeUpdate)
145 P->updateSizeAndAAInfo(Size, AAInfo);
146 }
147
148 Entry.setAliasSet(this);
149 Entry.updateSizeAndAAInfo(Size, AAInfo);
150
151 // Add it to the end of the list...
152 ++SetSize;
153 assert(*PtrListEnd == nullptr && "End of list is not null?");
154 *PtrListEnd = &Entry;
155 PtrListEnd = Entry.setPrevInList(PtrListEnd);
156 assert(*PtrListEnd == nullptr && "End of list is not null?");
157 // Entry points to alias set.
158 addRef();
159
160 if (Alias == SetMayAlias)
161 AST.TotalMayAliasSetSize++;
162 }
163
addUnknownInst(Instruction * I,BatchAAResults & AA)164 void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
165 if (UnknownInsts.empty())
166 addRef();
167 UnknownInsts.emplace_back(I);
168
169 // Guards are marked as modifying memory for control flow modelling purposes,
170 // but don't actually modify any specific memory location.
171 using namespace PatternMatch;
172 bool MayWriteMemory = I->mayWriteToMemory() && !isGuard(I) &&
173 !(I->use_empty() && match(I, m_Intrinsic<Intrinsic::invariant_start>()));
174 if (!MayWriteMemory) {
175 Alias = SetMayAlias;
176 Access |= RefAccess;
177 return;
178 }
179
180 // FIXME: This should use mod/ref information to make this not suck so bad
181 Alias = SetMayAlias;
182 Access = ModRefAccess;
183 }
184
185 /// aliasesPointer - If the specified pointer "may" (or must) alias one of the
186 /// members in the set return the appropriate AliasResult. Otherwise return
187 /// NoAlias.
188 ///
aliasesPointer(const Value * Ptr,LocationSize Size,const AAMDNodes & AAInfo,BatchAAResults & AA) const189 AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size,
190 const AAMDNodes &AAInfo,
191 BatchAAResults &AA) const {
192 if (AliasAny)
193 return AliasResult::MayAlias;
194
195 if (Alias == SetMustAlias) {
196 assert(UnknownInsts.empty() && "Illegal must alias set!");
197
198 // If this is a set of MustAliases, only check to see if the pointer aliases
199 // SOME value in the set.
200 PointerRec *SomePtr = getSomePointer();
201 assert(SomePtr && "Empty must-alias set??");
202 return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(),
203 SomePtr->getAAInfo()),
204 MemoryLocation(Ptr, Size, AAInfo));
205 }
206
207 // If this is a may-alias set, we have to check all of the pointers in the set
208 // to be sure it doesn't alias the set...
209 for (iterator I = begin(), E = end(); I != E; ++I) {
210 AliasResult AR =
211 AA.alias(MemoryLocation(Ptr, Size, AAInfo),
212 MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
213 if (AR != AliasResult::NoAlias)
214 return AR;
215 }
216
217 // Check the unknown instructions...
218 if (!UnknownInsts.empty()) {
219 for (Instruction *Inst : UnknownInsts)
220 if (isModOrRefSet(
221 AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo))))
222 return AliasResult::MayAlias;
223 }
224
225 return AliasResult::NoAlias;
226 }
227
aliasesUnknownInst(const Instruction * Inst,BatchAAResults & AA) const228 ModRefInfo AliasSet::aliasesUnknownInst(const Instruction *Inst,
229 BatchAAResults &AA) const {
230
231 if (AliasAny)
232 return ModRefInfo::ModRef;
233
234 if (!Inst->mayReadOrWriteMemory())
235 return ModRefInfo::NoModRef;
236
237 for (Instruction *UnknownInst : UnknownInsts) {
238 const auto *C1 = dyn_cast<CallBase>(UnknownInst);
239 const auto *C2 = dyn_cast<CallBase>(Inst);
240 if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
241 isModOrRefSet(AA.getModRefInfo(C2, C1))) {
242 // TODO: Could be more precise, but not really useful right now.
243 return ModRefInfo::ModRef;
244 }
245 }
246
247 ModRefInfo MR = ModRefInfo::NoModRef;
248 for (iterator I = begin(), E = end(); I != E; ++I) {
249 MR |= AA.getModRefInfo(
250 Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));
251 if (isModAndRefSet(MR))
252 return MR;
253 }
254
255 return MR;
256 }
257
clear()258 void AliasSetTracker::clear() {
259 // Delete all the PointerRec entries.
260 for (auto &I : PointerMap)
261 I.second->eraseFromList();
262
263 PointerMap.clear();
264
265 // The alias sets should all be clear now.
266 AliasSets.clear();
267 }
268
269 /// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may
270 /// alias the pointer. Return the unified set, or nullptr if no set that aliases
271 /// the pointer was found. MustAliasAll is updated to true/false if the pointer
272 /// is found to MustAlias all the sets it merged.
mergeAliasSetsForPointer(const Value * Ptr,LocationSize Size,const AAMDNodes & AAInfo,bool & MustAliasAll)273 AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr,
274 LocationSize Size,
275 const AAMDNodes &AAInfo,
276 bool &MustAliasAll) {
277 AliasSet *FoundSet = nullptr;
278 MustAliasAll = true;
279 for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
280 if (AS.Forward)
281 continue;
282
283 AliasResult AR = AS.aliasesPointer(Ptr, Size, AAInfo, AA);
284 if (AR == AliasResult::NoAlias)
285 continue;
286
287 if (AR != AliasResult::MustAlias)
288 MustAliasAll = false;
289
290 if (!FoundSet) {
291 // If this is the first alias set ptr can go into, remember it.
292 FoundSet = &AS;
293 } else {
294 // Otherwise, we must merge the sets.
295 FoundSet->mergeSetIn(AS, *this, AA);
296 }
297 }
298
299 return FoundSet;
300 }
301
findAliasSetForUnknownInst(Instruction * Inst)302 AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
303 AliasSet *FoundSet = nullptr;
304 for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
305 if (AS.Forward || !isModOrRefSet(AS.aliasesUnknownInst(Inst, AA)))
306 continue;
307 if (!FoundSet) {
308 // If this is the first alias set ptr can go into, remember it.
309 FoundSet = &AS;
310 } else {
311 // Otherwise, we must merge the sets.
312 FoundSet->mergeSetIn(AS, *this, AA);
313 }
314 }
315 return FoundSet;
316 }
317
getAliasSetFor(const MemoryLocation & MemLoc)318 AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) {
319
320 Value * const Pointer = const_cast<Value*>(MemLoc.Ptr);
321 const LocationSize Size = MemLoc.Size;
322 const AAMDNodes &AAInfo = MemLoc.AATags;
323
324 AliasSet::PointerRec &Entry = getEntryFor(Pointer);
325
326 if (AliasAnyAS) {
327 // At this point, the AST is saturated, so we only have one active alias
328 // set. That means we already know which alias set we want to return, and
329 // just need to add the pointer to that set to keep the data structure
330 // consistent.
331 // This, of course, means that we will never need a merge here.
332 if (Entry.hasAliasSet()) {
333 Entry.updateSizeAndAAInfo(Size, AAInfo);
334 assert(Entry.getAliasSet(*this) == AliasAnyAS &&
335 "Entry in saturated AST must belong to only alias set");
336 } else {
337 AliasAnyAS->addPointer(*this, Entry, Size, AAInfo);
338 }
339 return *AliasAnyAS;
340 }
341
342 bool MustAliasAll = false;
343 // Check to see if the pointer is already known.
344 if (Entry.hasAliasSet()) {
345 // If the size changed, we may need to merge several alias sets.
346 // Note that we can *not* return the result of mergeAliasSetsForPointer
347 // due to a quirk of alias analysis behavior. Since alias(undef, undef)
348 // is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the
349 // the right set for undef, even if it exists.
350 if (Entry.updateSizeAndAAInfo(Size, AAInfo))
351 mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll);
352 // Return the set!
353 return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
354 }
355
356 if (AliasSet *AS =
357 mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll)) {
358 // Add it to the alias set it aliases.
359 AS->addPointer(*this, Entry, Size, AAInfo, MustAliasAll);
360 return *AS;
361 }
362
363 // Otherwise create a new alias set to hold the loaded pointer.
364 AliasSets.push_back(new AliasSet());
365 AliasSets.back().addPointer(*this, Entry, Size, AAInfo, true);
366 return AliasSets.back();
367 }
368
add(Value * Ptr,LocationSize Size,const AAMDNodes & AAInfo)369 void AliasSetTracker::add(Value *Ptr, LocationSize Size,
370 const AAMDNodes &AAInfo) {
371 addPointer(MemoryLocation(Ptr, Size, AAInfo), AliasSet::NoAccess);
372 }
373
add(LoadInst * LI)374 void AliasSetTracker::add(LoadInst *LI) {
375 if (isStrongerThanMonotonic(LI->getOrdering()))
376 return addUnknown(LI);
377 addPointer(MemoryLocation::get(LI), AliasSet::RefAccess);
378 }
379
add(StoreInst * SI)380 void AliasSetTracker::add(StoreInst *SI) {
381 if (isStrongerThanMonotonic(SI->getOrdering()))
382 return addUnknown(SI);
383 addPointer(MemoryLocation::get(SI), AliasSet::ModAccess);
384 }
385
add(VAArgInst * VAAI)386 void AliasSetTracker::add(VAArgInst *VAAI) {
387 addPointer(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
388 }
389
add(AnyMemSetInst * MSI)390 void AliasSetTracker::add(AnyMemSetInst *MSI) {
391 addPointer(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
392 }
393
add(AnyMemTransferInst * MTI)394 void AliasSetTracker::add(AnyMemTransferInst *MTI) {
395 addPointer(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
396 addPointer(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
397 }
398
addUnknown(Instruction * Inst)399 void AliasSetTracker::addUnknown(Instruction *Inst) {
400 if (isa<DbgInfoIntrinsic>(Inst))
401 return; // Ignore DbgInfo Intrinsics.
402
403 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
404 // These intrinsics will show up as affecting memory, but they are just
405 // markers.
406 switch (II->getIntrinsicID()) {
407 default:
408 break;
409 // FIXME: Add lifetime/invariant intrinsics (See: PR30807).
410 case Intrinsic::assume:
411 case Intrinsic::experimental_noalias_scope_decl:
412 case Intrinsic::sideeffect:
413 case Intrinsic::pseudoprobe:
414 return;
415 }
416 }
417 if (!Inst->mayReadOrWriteMemory())
418 return; // doesn't alias anything
419
420 if (AliasSet *AS = findAliasSetForUnknownInst(Inst)) {
421 AS->addUnknownInst(Inst, AA);
422 return;
423 }
424 AliasSets.push_back(new AliasSet());
425 AliasSets.back().addUnknownInst(Inst, AA);
426 }
427
add(Instruction * I)428 void AliasSetTracker::add(Instruction *I) {
429 // Dispatch to one of the other add methods.
430 if (LoadInst *LI = dyn_cast<LoadInst>(I))
431 return add(LI);
432 if (StoreInst *SI = dyn_cast<StoreInst>(I))
433 return add(SI);
434 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
435 return add(VAAI);
436 if (AnyMemSetInst *MSI = dyn_cast<AnyMemSetInst>(I))
437 return add(MSI);
438 if (AnyMemTransferInst *MTI = dyn_cast<AnyMemTransferInst>(I))
439 return add(MTI);
440
441 // Handle all calls with known mod/ref sets genericall
442 if (auto *Call = dyn_cast<CallBase>(I))
443 if (Call->onlyAccessesArgMemory()) {
444 auto getAccessFromModRef = [](ModRefInfo MRI) {
445 if (isRefSet(MRI) && isModSet(MRI))
446 return AliasSet::ModRefAccess;
447 else if (isModSet(MRI))
448 return AliasSet::ModAccess;
449 else if (isRefSet(MRI))
450 return AliasSet::RefAccess;
451 else
452 return AliasSet::NoAccess;
453 };
454
455 ModRefInfo CallMask = AA.getMemoryEffects(Call).getModRef();
456
457 // Some intrinsics are marked as modifying memory for control flow
458 // modelling purposes, but don't actually modify any specific memory
459 // location.
460 using namespace PatternMatch;
461 if (Call->use_empty() &&
462 match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
463 CallMask &= ModRefInfo::Ref;
464
465 for (auto IdxArgPair : enumerate(Call->args())) {
466 int ArgIdx = IdxArgPair.index();
467 const Value *Arg = IdxArgPair.value();
468 if (!Arg->getType()->isPointerTy())
469 continue;
470 MemoryLocation ArgLoc =
471 MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
472 ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
473 ArgMask &= CallMask;
474 if (!isNoModRef(ArgMask))
475 addPointer(ArgLoc, getAccessFromModRef(ArgMask));
476 }
477 return;
478 }
479
480 return addUnknown(I);
481 }
482
add(BasicBlock & BB)483 void AliasSetTracker::add(BasicBlock &BB) {
484 for (auto &I : BB)
485 add(&I);
486 }
487
add(const AliasSetTracker & AST)488 void AliasSetTracker::add(const AliasSetTracker &AST) {
489 assert(&AA == &AST.AA &&
490 "Merging AliasSetTracker objects with different Alias Analyses!");
491
492 // Loop over all of the alias sets in AST, adding the pointers contained
493 // therein into the current alias sets. This can cause alias sets to be
494 // merged together in the current AST.
495 for (const AliasSet &AS : AST) {
496 if (AS.Forward)
497 continue; // Ignore forwarding alias sets
498
499 // If there are any call sites in the alias set, add them to this AST.
500 for (Instruction *Inst : AS.UnknownInsts)
501 add(Inst);
502
503 // Loop over all of the pointers in this alias set.
504 for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI)
505 addPointer(
506 MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()),
507 (AliasSet::AccessLattice)AS.Access);
508 }
509 }
510
mergeAllAliasSets()511 AliasSet &AliasSetTracker::mergeAllAliasSets() {
512 assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) &&
513 "Full merge should happen once, when the saturation threshold is "
514 "reached");
515
516 // Collect all alias sets, so that we can drop references with impunity
517 // without worrying about iterator invalidation.
518 std::vector<AliasSet *> ASVector;
519 ASVector.reserve(SaturationThreshold);
520 for (AliasSet &AS : *this)
521 ASVector.push_back(&AS);
522
523 // Copy all instructions and pointers into a new set, and forward all other
524 // sets to it.
525 AliasSets.push_back(new AliasSet());
526 AliasAnyAS = &AliasSets.back();
527 AliasAnyAS->Alias = AliasSet::SetMayAlias;
528 AliasAnyAS->Access = AliasSet::ModRefAccess;
529 AliasAnyAS->AliasAny = true;
530
531 for (auto *Cur : ASVector) {
532 // If Cur was already forwarding, just forward to the new AS instead.
533 AliasSet *FwdTo = Cur->Forward;
534 if (FwdTo) {
535 Cur->Forward = AliasAnyAS;
536 AliasAnyAS->addRef();
537 FwdTo->dropRef(*this);
538 continue;
539 }
540
541 // Otherwise, perform the actual merge.
542 AliasAnyAS->mergeSetIn(*Cur, *this, AA);
543 }
544
545 return *AliasAnyAS;
546 }
547
addPointer(MemoryLocation Loc,AliasSet::AccessLattice E)548 AliasSet &AliasSetTracker::addPointer(MemoryLocation Loc,
549 AliasSet::AccessLattice E) {
550 AliasSet &AS = getAliasSetFor(Loc);
551 AS.Access |= E;
552
553 if (!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold)) {
554 // The AST is now saturated. From here on, we conservatively consider all
555 // pointers to alias each-other.
556 return mergeAllAliasSets();
557 }
558
559 return AS;
560 }
561
562 //===----------------------------------------------------------------------===//
563 // AliasSet/AliasSetTracker Printing Support
564 //===----------------------------------------------------------------------===//
565
print(raw_ostream & OS) const566 void AliasSet::print(raw_ostream &OS) const {
567 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] ";
568 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
569 switch (Access) {
570 case NoAccess: OS << "No access "; break;
571 case RefAccess: OS << "Ref "; break;
572 case ModAccess: OS << "Mod "; break;
573 case ModRefAccess: OS << "Mod/Ref "; break;
574 default: llvm_unreachable("Bad value for Access!");
575 }
576 if (Forward)
577 OS << " forwarding to " << (void*)Forward;
578
579 if (!empty()) {
580 OS << "Pointers: ";
581 for (iterator I = begin(), E = end(); I != E; ++I) {
582 if (I != begin()) OS << ", ";
583 I.getPointer()->printAsOperand(OS << "(");
584 if (I.getSize() == LocationSize::afterPointer())
585 OS << ", unknown after)";
586 else if (I.getSize() == LocationSize::beforeOrAfterPointer())
587 OS << ", unknown before-or-after)";
588 else
589 OS << ", " << I.getSize() << ")";
590 }
591 }
592 if (!UnknownInsts.empty()) {
593 ListSeparator LS;
594 OS << "\n " << UnknownInsts.size() << " Unknown instructions: ";
595 for (Instruction *I : UnknownInsts) {
596 OS << LS;
597 if (I->hasName())
598 I->printAsOperand(OS);
599 else
600 I->print(OS);
601 }
602 }
603 OS << "\n";
604 }
605
print(raw_ostream & OS) const606 void AliasSetTracker::print(raw_ostream &OS) const {
607 OS << "Alias Set Tracker: " << AliasSets.size();
608 if (AliasAnyAS)
609 OS << " (Saturated)";
610 OS << " alias sets for " << PointerMap.size() << " pointer values.\n";
611 for (const AliasSet &AS : *this)
612 AS.print(OS);
613 OS << "\n";
614 }
615
616 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const617 LLVM_DUMP_METHOD void AliasSet::dump() const { print(dbgs()); }
dump() const618 LLVM_DUMP_METHOD void AliasSetTracker::dump() const { print(dbgs()); }
619 #endif
620
621 //===----------------------------------------------------------------------===//
622 // AliasSetPrinter Pass
623 //===----------------------------------------------------------------------===//
624
AliasSetsPrinterPass(raw_ostream & OS)625 AliasSetsPrinterPass::AliasSetsPrinterPass(raw_ostream &OS) : OS(OS) {}
626
run(Function & F,FunctionAnalysisManager & AM)627 PreservedAnalyses AliasSetsPrinterPass::run(Function &F,
628 FunctionAnalysisManager &AM) {
629 auto &AA = AM.getResult<AAManager>(F);
630 BatchAAResults BatchAA(AA);
631 AliasSetTracker Tracker(BatchAA);
632 OS << "Alias sets for function '" << F.getName() << "':\n";
633 for (Instruction &I : instructions(F))
634 Tracker.add(&I);
635 Tracker.print(OS);
636 return PreservedAnalyses::all();
637 }
638