AliasSetTracker.cpp revision f3ef5332fa3f4d5ec72c178a2b19dac363a19383
1//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===// 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// 10// This file implements the AliasSetTracker and AliasSet classes. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/Analysis/AliasSetTracker.h" 15#include "llvm/Analysis/AliasAnalysis.h" 16#include "llvm/IR/DataLayout.h" 17#include "llvm/IR/InstIterator.h" 18#include "llvm/IR/Instructions.h" 19#include "llvm/IR/IntrinsicInst.h" 20#include "llvm/IR/Module.h" 21#include "llvm/IR/LLVMContext.h" 22#include "llvm/IR/Type.h" 23#include "llvm/Pass.h" 24#include "llvm/Support/Debug.h" 25#include "llvm/Support/ErrorHandling.h" 26#include "llvm/Support/raw_ostream.h" 27using namespace llvm; 28 29/// mergeSetIn - Merge the specified alias set into this alias set. 30/// 31void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) { 32 assert(!AS.Forward && "Alias set is already forwarding!"); 33 assert(!Forward && "This set is a forwarding set!!"); 34 35 // Update the alias and access types of this set... 36 Access |= AS.Access; 37 Alias |= AS.Alias; 38 Volatile |= AS.Volatile; 39 40 if (Alias == SetMustAlias) { 41 // Check that these two merged sets really are must aliases. Since both 42 // used to be must-alias sets, we can just check any pointer from each set 43 // for aliasing. 44 AliasAnalysis &AA = AST.getAliasAnalysis(); 45 PointerRec *L = getSomePointer(); 46 PointerRec *R = AS.getSomePointer(); 47 48 // If the pointers are not a must-alias pair, this set becomes a may alias. 49 if (AA.alias(MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()), 50 MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())) != 51 MustAlias) 52 Alias = SetMayAlias; 53 } 54 55 bool ASHadUnknownInsts = !AS.UnknownInsts.empty(); 56 if (UnknownInsts.empty()) { // Merge call sites... 57 if (ASHadUnknownInsts) { 58 std::swap(UnknownInsts, AS.UnknownInsts); 59 addRef(); 60 } 61 } else if (ASHadUnknownInsts) { 62 UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end()); 63 AS.UnknownInsts.clear(); 64 } 65 66 AS.Forward = this; // Forward across AS now... 67 addRef(); // AS is now pointing to us... 68 69 // Merge the list of constituent pointers... 70 if (AS.PtrList) { 71 *PtrListEnd = AS.PtrList; 72 AS.PtrList->setPrevInList(PtrListEnd); 73 PtrListEnd = AS.PtrListEnd; 74 75 AS.PtrList = nullptr; 76 AS.PtrListEnd = &AS.PtrList; 77 assert(*AS.PtrListEnd == nullptr && "End of list is not null?"); 78 } 79 if (ASHadUnknownInsts) 80 AS.dropRef(AST); 81} 82 83void AliasSetTracker::removeAliasSet(AliasSet *AS) { 84 if (AliasSet *Fwd = AS->Forward) { 85 Fwd->dropRef(*this); 86 AS->Forward = nullptr; 87 } 88 AliasSets.erase(AS); 89} 90 91void AliasSet::removeFromTracker(AliasSetTracker &AST) { 92 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!"); 93 AST.removeAliasSet(this); 94} 95 96void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry, 97 uint64_t Size, const AAMDNodes &AAInfo, 98 bool KnownMustAlias) { 99 assert(!Entry.hasAliasSet() && "Entry already in set!"); 100 101 // Check to see if we have to downgrade to _may_ alias. 102 if (isMustAlias() && !KnownMustAlias) 103 if (PointerRec *P = getSomePointer()) { 104 AliasAnalysis &AA = AST.getAliasAnalysis(); 105 AliasResult Result = 106 AA.alias(MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()), 107 MemoryLocation(Entry.getValue(), Size, AAInfo)); 108 if (Result != MustAlias) 109 Alias = SetMayAlias; 110 else // First entry of must alias must have maximum size! 111 P->updateSizeAndAAInfo(Size, AAInfo); 112 assert(Result != NoAlias && "Cannot be part of must set!"); 113 } 114 115 Entry.setAliasSet(this); 116 Entry.updateSizeAndAAInfo(Size, AAInfo); 117 118 // Add it to the end of the list... 119 assert(*PtrListEnd == nullptr && "End of list is not null?"); 120 *PtrListEnd = &Entry; 121 PtrListEnd = Entry.setPrevInList(PtrListEnd); 122 assert(*PtrListEnd == nullptr && "End of list is not null?"); 123 addRef(); // Entry points to alias set. 124} 125 126void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) { 127 if (UnknownInsts.empty()) 128 addRef(); 129 UnknownInsts.emplace_back(I); 130 131 if (!I->mayWriteToMemory()) { 132 Alias = SetMayAlias; 133 Access |= RefAccess; 134 return; 135 } 136 137 // FIXME: This should use mod/ref information to make this not suck so bad 138 Alias = SetMayAlias; 139 Access = ModRefAccess; 140} 141 142/// aliasesPointer - Return true if the specified pointer "may" (or must) 143/// alias one of the members in the set. 144/// 145bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size, 146 const AAMDNodes &AAInfo, 147 AliasAnalysis &AA) const { 148 if (Alias == SetMustAlias) { 149 assert(UnknownInsts.empty() && "Illegal must alias set!"); 150 151 // If this is a set of MustAliases, only check to see if the pointer aliases 152 // SOME value in the set. 153 PointerRec *SomePtr = getSomePointer(); 154 assert(SomePtr && "Empty must-alias set??"); 155 return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(), 156 SomePtr->getAAInfo()), 157 MemoryLocation(Ptr, Size, AAInfo)); 158 } 159 160 // If this is a may-alias set, we have to check all of the pointers in the set 161 // to be sure it doesn't alias the set... 162 for (iterator I = begin(), E = end(); I != E; ++I) 163 if (AA.alias(MemoryLocation(Ptr, Size, AAInfo), 164 MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))) 165 return true; 166 167 // Check the unknown instructions... 168 if (!UnknownInsts.empty()) { 169 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) 170 if (AA.getModRefInfo(UnknownInsts[i], 171 MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef) 172 return true; 173 } 174 175 return false; 176} 177 178bool AliasSet::aliasesUnknownInst(const Instruction *Inst, 179 AliasAnalysis &AA) const { 180 if (!Inst->mayReadOrWriteMemory()) 181 return false; 182 183 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { 184 ImmutableCallSite C1(getUnknownInst(i)), C2(Inst); 185 if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef || 186 AA.getModRefInfo(C2, C1) != MRI_NoModRef) 187 return true; 188 } 189 190 for (iterator I = begin(), E = end(); I != E; ++I) 191 if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(), 192 I.getAAInfo())) != MRI_NoModRef) 193 return true; 194 195 return false; 196} 197 198void AliasSetTracker::clear() { 199 // Delete all the PointerRec entries. 200 for (PointerMapType::iterator I = PointerMap.begin(), E = PointerMap.end(); 201 I != E; ++I) 202 I->second->eraseFromList(); 203 204 PointerMap.clear(); 205 206 // The alias sets should all be clear now. 207 AliasSets.clear(); 208} 209 210 211/// findAliasSetForPointer - Given a pointer, find the one alias set to put the 212/// instruction referring to the pointer into. If there are multiple alias sets 213/// that may alias the pointer, merge them together and return the unified set. 214/// 215AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr, 216 uint64_t Size, 217 const AAMDNodes &AAInfo) { 218 AliasSet *FoundSet = nullptr; 219 for (iterator I = begin(), E = end(); I != E;) { 220 iterator Cur = I++; 221 if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA)) continue; 222 223 if (!FoundSet) { // If this is the first alias set ptr can go into. 224 FoundSet = &*Cur; // Remember it. 225 } else { // Otherwise, we must merge the sets. 226 FoundSet->mergeSetIn(*Cur, *this); // Merge in contents. 227 } 228 } 229 230 return FoundSet; 231} 232 233/// containsPointer - Return true if the specified location is represented by 234/// this alias set, false otherwise. This does not modify the AST object or 235/// alias sets. 236bool AliasSetTracker::containsPointer(const Value *Ptr, uint64_t Size, 237 const AAMDNodes &AAInfo) const { 238 for (const_iterator I = begin(), E = end(); I != E; ++I) 239 if (!I->Forward && I->aliasesPointer(Ptr, Size, AAInfo, AA)) 240 return true; 241 return false; 242} 243 244bool AliasSetTracker::containsUnknown(const Instruction *Inst) const { 245 for (const_iterator I = begin(), E = end(); I != E; ++I) 246 if (!I->Forward && I->aliasesUnknownInst(Inst, AA)) 247 return true; 248 return false; 249} 250 251AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) { 252 AliasSet *FoundSet = nullptr; 253 for (iterator I = begin(), E = end(); I != E;) { 254 iterator Cur = I++; 255 if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA)) 256 continue; 257 if (!FoundSet) // If this is the first alias set ptr can go into. 258 FoundSet = &*Cur; // Remember it. 259 else if (!Cur->Forward) // Otherwise, we must merge the sets. 260 FoundSet->mergeSetIn(*Cur, *this); // Merge in contents. 261 } 262 return FoundSet; 263} 264 265 266 267 268/// getAliasSetForPointer - Return the alias set that the specified pointer 269/// lives in. 270AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, uint64_t Size, 271 const AAMDNodes &AAInfo, 272 bool *New) { 273 AliasSet::PointerRec &Entry = getEntryFor(Pointer); 274 275 // Check to see if the pointer is already known. 276 if (Entry.hasAliasSet()) { 277 Entry.updateSizeAndAAInfo(Size, AAInfo); 278 // Return the set! 279 return *Entry.getAliasSet(*this)->getForwardedTarget(*this); 280 } 281 282 if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, AAInfo)) { 283 // Add it to the alias set it aliases. 284 AS->addPointer(*this, Entry, Size, AAInfo); 285 return *AS; 286 } 287 288 if (New) *New = true; 289 // Otherwise create a new alias set to hold the loaded pointer. 290 AliasSets.push_back(new AliasSet()); 291 AliasSets.back().addPointer(*this, Entry, Size, AAInfo); 292 return AliasSets.back(); 293} 294 295bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) { 296 bool NewPtr; 297 addPointer(Ptr, Size, AAInfo, AliasSet::NoAccess, NewPtr); 298 return NewPtr; 299} 300 301 302bool AliasSetTracker::add(LoadInst *LI) { 303 if (LI->getOrdering() > Monotonic) return addUnknown(LI); 304 305 AAMDNodes AAInfo; 306 LI->getAAMetadata(AAInfo); 307 308 AliasSet::AccessLattice Access = AliasSet::RefAccess; 309 bool NewPtr; 310 const DataLayout &DL = LI->getModule()->getDataLayout(); 311 AliasSet &AS = addPointer(LI->getOperand(0), 312 DL.getTypeStoreSize(LI->getType()), 313 AAInfo, Access, NewPtr); 314 if (LI->isVolatile()) AS.setVolatile(); 315 return NewPtr; 316} 317 318bool AliasSetTracker::add(StoreInst *SI) { 319 if (SI->getOrdering() > Monotonic) return addUnknown(SI); 320 321 AAMDNodes AAInfo; 322 SI->getAAMetadata(AAInfo); 323 324 AliasSet::AccessLattice Access = AliasSet::ModAccess; 325 bool NewPtr; 326 const DataLayout &DL = SI->getModule()->getDataLayout(); 327 Value *Val = SI->getOperand(0); 328 AliasSet &AS = addPointer(SI->getOperand(1), 329 DL.getTypeStoreSize(Val->getType()), 330 AAInfo, Access, NewPtr); 331 if (SI->isVolatile()) AS.setVolatile(); 332 return NewPtr; 333} 334 335bool AliasSetTracker::add(VAArgInst *VAAI) { 336 AAMDNodes AAInfo; 337 VAAI->getAAMetadata(AAInfo); 338 339 bool NewPtr; 340 addPointer(VAAI->getOperand(0), MemoryLocation::UnknownSize, AAInfo, 341 AliasSet::ModRefAccess, NewPtr); 342 return NewPtr; 343} 344 345 346bool AliasSetTracker::addUnknown(Instruction *Inst) { 347 if (isa<DbgInfoIntrinsic>(Inst)) 348 return true; // Ignore DbgInfo Intrinsics. 349 if (!Inst->mayReadOrWriteMemory()) 350 return true; // doesn't alias anything 351 352 AliasSet *AS = findAliasSetForUnknownInst(Inst); 353 if (AS) { 354 AS->addUnknownInst(Inst, AA); 355 return false; 356 } 357 AliasSets.push_back(new AliasSet()); 358 AS = &AliasSets.back(); 359 AS->addUnknownInst(Inst, AA); 360 return true; 361} 362 363bool AliasSetTracker::add(Instruction *I) { 364 // Dispatch to one of the other add methods. 365 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 366 return add(LI); 367 if (StoreInst *SI = dyn_cast<StoreInst>(I)) 368 return add(SI); 369 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I)) 370 return add(VAAI); 371 return addUnknown(I); 372} 373 374void AliasSetTracker::add(BasicBlock &BB) { 375 for (auto &I : BB) 376 add(&I); 377} 378 379void AliasSetTracker::add(const AliasSetTracker &AST) { 380 assert(&AA == &AST.AA && 381 "Merging AliasSetTracker objects with different Alias Analyses!"); 382 383 // Loop over all of the alias sets in AST, adding the pointers contained 384 // therein into the current alias sets. This can cause alias sets to be 385 // merged together in the current AST. 386 for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) { 387 if (I->Forward) continue; // Ignore forwarding alias sets 388 389 AliasSet &AS = const_cast<AliasSet&>(*I); 390 391 // If there are any call sites in the alias set, add them to this AST. 392 for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i) 393 add(AS.UnknownInsts[i]); 394 395 // Loop over all of the pointers in this alias set. 396 bool X; 397 for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) { 398 AliasSet &NewAS = addPointer(ASI.getPointer(), ASI.getSize(), 399 ASI.getAAInfo(), 400 (AliasSet::AccessLattice)AS.Access, X); 401 if (AS.isVolatile()) NewAS.setVolatile(); 402 } 403 } 404} 405 406/// remove - Remove the specified (potentially non-empty) alias set from the 407/// tracker. 408void AliasSetTracker::remove(AliasSet &AS) { 409 // Drop all call sites. 410 if (!AS.UnknownInsts.empty()) 411 AS.dropRef(*this); 412 AS.UnknownInsts.clear(); 413 414 // Clear the alias set. 415 unsigned NumRefs = 0; 416 while (!AS.empty()) { 417 AliasSet::PointerRec *P = AS.PtrList; 418 419 Value *ValToRemove = P->getValue(); 420 421 // Unlink and delete entry from the list of values. 422 P->eraseFromList(); 423 424 // Remember how many references need to be dropped. 425 ++NumRefs; 426 427 // Finally, remove the entry. 428 PointerMap.erase(ValToRemove); 429 } 430 431 // Stop using the alias set, removing it. 432 AS.RefCount -= NumRefs; 433 if (AS.RefCount == 0) 434 AS.removeFromTracker(*this); 435} 436 437bool 438AliasSetTracker::remove(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo) { 439 AliasSet *AS = findAliasSetForPointer(Ptr, Size, AAInfo); 440 if (!AS) return false; 441 remove(*AS); 442 return true; 443} 444 445bool AliasSetTracker::remove(LoadInst *LI) { 446 const DataLayout &DL = LI->getModule()->getDataLayout(); 447 uint64_t Size = DL.getTypeStoreSize(LI->getType()); 448 449 AAMDNodes AAInfo; 450 LI->getAAMetadata(AAInfo); 451 452 AliasSet *AS = findAliasSetForPointer(LI->getOperand(0), Size, AAInfo); 453 if (!AS) return false; 454 remove(*AS); 455 return true; 456} 457 458bool AliasSetTracker::remove(StoreInst *SI) { 459 const DataLayout &DL = SI->getModule()->getDataLayout(); 460 uint64_t Size = DL.getTypeStoreSize(SI->getOperand(0)->getType()); 461 462 AAMDNodes AAInfo; 463 SI->getAAMetadata(AAInfo); 464 465 AliasSet *AS = findAliasSetForPointer(SI->getOperand(1), Size, AAInfo); 466 if (!AS) return false; 467 remove(*AS); 468 return true; 469} 470 471bool AliasSetTracker::remove(VAArgInst *VAAI) { 472 AAMDNodes AAInfo; 473 VAAI->getAAMetadata(AAInfo); 474 475 AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0), 476 MemoryLocation::UnknownSize, AAInfo); 477 if (!AS) return false; 478 remove(*AS); 479 return true; 480} 481 482bool AliasSetTracker::removeUnknown(Instruction *I) { 483 if (!I->mayReadOrWriteMemory()) 484 return false; // doesn't alias anything 485 486 AliasSet *AS = findAliasSetForUnknownInst(I); 487 if (!AS) return false; 488 remove(*AS); 489 return true; 490} 491 492bool AliasSetTracker::remove(Instruction *I) { 493 // Dispatch to one of the other remove methods... 494 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 495 return remove(LI); 496 if (StoreInst *SI = dyn_cast<StoreInst>(I)) 497 return remove(SI); 498 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I)) 499 return remove(VAAI); 500 return removeUnknown(I); 501} 502 503 504// deleteValue method - This method is used to remove a pointer value from the 505// AliasSetTracker entirely. It should be used when an instruction is deleted 506// from the program to update the AST. If you don't use this, you would have 507// dangling pointers to deleted instructions. 508// 509void AliasSetTracker::deleteValue(Value *PtrVal) { 510 // If this is a call instruction, remove the callsite from the appropriate 511 // AliasSet (if present). 512 if (Instruction *Inst = dyn_cast<Instruction>(PtrVal)) { 513 if (Inst->mayReadOrWriteMemory()) { 514 // Scan all the alias sets to see if this call site is contained. 515 for (iterator I = begin(), E = end(); I != E;) { 516 iterator Cur = I++; 517 if (!Cur->Forward) 518 Cur->removeUnknownInst(*this, Inst); 519 } 520 } 521 } 522 523 // First, look up the PointerRec for this pointer. 524 PointerMapType::iterator I = PointerMap.find_as(PtrVal); 525 if (I == PointerMap.end()) return; // Noop 526 527 // If we found one, remove the pointer from the alias set it is in. 528 AliasSet::PointerRec *PtrValEnt = I->second; 529 AliasSet *AS = PtrValEnt->getAliasSet(*this); 530 531 // Unlink and delete from the list of values. 532 PtrValEnt->eraseFromList(); 533 534 // Stop using the alias set. 535 AS->dropRef(*this); 536 537 PointerMap.erase(I); 538} 539 540// copyValue - This method should be used whenever a preexisting value in the 541// program is copied or cloned, introducing a new value. Note that it is ok for 542// clients that use this method to introduce the same value multiple times: if 543// the tracker already knows about a value, it will ignore the request. 544// 545void AliasSetTracker::copyValue(Value *From, Value *To) { 546 // First, look up the PointerRec for this pointer. 547 PointerMapType::iterator I = PointerMap.find_as(From); 548 if (I == PointerMap.end()) 549 return; // Noop 550 assert(I->second->hasAliasSet() && "Dead entry?"); 551 552 AliasSet::PointerRec &Entry = getEntryFor(To); 553 if (Entry.hasAliasSet()) return; // Already in the tracker! 554 555 // Add it to the alias set it aliases... 556 I = PointerMap.find_as(From); 557 AliasSet *AS = I->second->getAliasSet(*this); 558 AS->addPointer(*this, Entry, I->second->getSize(), 559 I->second->getAAInfo(), 560 true); 561} 562 563 564 565//===----------------------------------------------------------------------===// 566// AliasSet/AliasSetTracker Printing Support 567//===----------------------------------------------------------------------===// 568 569void AliasSet::print(raw_ostream &OS) const { 570 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] "; 571 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, "; 572 switch (Access) { 573 case NoAccess: OS << "No access "; break; 574 case RefAccess: OS << "Ref "; break; 575 case ModAccess: OS << "Mod "; break; 576 case ModRefAccess: OS << "Mod/Ref "; break; 577 default: llvm_unreachable("Bad value for Access!"); 578 } 579 if (isVolatile()) OS << "[volatile] "; 580 if (Forward) 581 OS << " forwarding to " << (void*)Forward; 582 583 584 if (!empty()) { 585 OS << "Pointers: "; 586 for (iterator I = begin(), E = end(); I != E; ++I) { 587 if (I != begin()) OS << ", "; 588 I.getPointer()->printAsOperand(OS << "("); 589 OS << ", " << I.getSize() << ")"; 590 } 591 } 592 if (!UnknownInsts.empty()) { 593 OS << "\n " << UnknownInsts.size() << " Unknown instructions: "; 594 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { 595 if (i) OS << ", "; 596 UnknownInsts[i]->printAsOperand(OS); 597 } 598 } 599 OS << "\n"; 600} 601 602void AliasSetTracker::print(raw_ostream &OS) const { 603 OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for " 604 << PointerMap.size() << " pointer values.\n"; 605 for (const_iterator I = begin(), E = end(); I != E; ++I) 606 I->print(OS); 607 OS << "\n"; 608} 609 610#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 611void AliasSet::dump() const { print(dbgs()); } 612void AliasSetTracker::dump() const { print(dbgs()); } 613#endif 614 615//===----------------------------------------------------------------------===// 616// ASTCallbackVH Class Implementation 617//===----------------------------------------------------------------------===// 618 619void AliasSetTracker::ASTCallbackVH::deleted() { 620 assert(AST && "ASTCallbackVH called with a null AliasSetTracker!"); 621 AST->deleteValue(getValPtr()); 622 // this now dangles! 623} 624 625void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) { 626 AST->copyValue(getValPtr(), V); 627} 628 629AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast) 630 : CallbackVH(V), AST(ast) {} 631 632AliasSetTracker::ASTCallbackVH & 633AliasSetTracker::ASTCallbackVH::operator=(Value *V) { 634 return *this = ASTCallbackVH(V, AST); 635} 636 637//===----------------------------------------------------------------------===// 638// AliasSetPrinter Pass 639//===----------------------------------------------------------------------===// 640 641namespace { 642 class AliasSetPrinter : public FunctionPass { 643 AliasSetTracker *Tracker; 644 public: 645 static char ID; // Pass identification, replacement for typeid 646 AliasSetPrinter() : FunctionPass(ID) { 647 initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry()); 648 } 649 650 void getAnalysisUsage(AnalysisUsage &AU) const override { 651 AU.setPreservesAll(); 652 AU.addRequired<AAResultsWrapperPass>(); 653 } 654 655 bool runOnFunction(Function &F) override { 656 auto &AAWP = getAnalysis<AAResultsWrapperPass>(); 657 Tracker = new AliasSetTracker(AAWP.getAAResults()); 658 659 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) 660 Tracker->add(&*I); 661 Tracker->print(errs()); 662 delete Tracker; 663 return false; 664 } 665 }; 666} 667 668char AliasSetPrinter::ID = 0; 669INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets", 670 "Alias Set Printer", false, true) 671INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 672INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets", 673 "Alias Set Printer", false, true) 674