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. 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 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 121 void AliasSet::removeFromTracker(AliasSetTracker &AST) { 122 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!"); 123 AST.removeAliasSet(this); 124 } 125 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 AliasAnalysis &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 164 void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &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 /// 189 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 (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) 220 if (auto *Inst = getUnknownInst(i)) 221 if (isModOrRefSet( 222 AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)))) 223 return AliasResult::MayAlias; 224 } 225 226 return AliasResult::NoAlias; 227 } 228 229 bool AliasSet::aliasesUnknownInst(const Instruction *Inst, 230 BatchAAResults &AA) const { 231 232 if (AliasAny) 233 return true; 234 235 if (!Inst->mayReadOrWriteMemory()) 236 return false; 237 238 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { 239 if (auto *UnknownInst = getUnknownInst(i)) { 240 const auto *C1 = dyn_cast<CallBase>(UnknownInst); 241 const auto *C2 = dyn_cast<CallBase>(Inst); 242 if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) || 243 isModOrRefSet(AA.getModRefInfo(C2, C1))) 244 return true; 245 } 246 } 247 248 for (iterator I = begin(), E = end(); I != E; ++I) 249 if (isModOrRefSet(AA.getModRefInfo( 250 Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))) 251 return true; 252 253 return false; 254 } 255 256 void AliasSetTracker::clear() { 257 // Delete all the PointerRec entries. 258 for (auto &I : PointerMap) 259 I.second->eraseFromList(); 260 261 PointerMap.clear(); 262 263 // The alias sets should all be clear now. 264 AliasSets.clear(); 265 } 266 267 /// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may 268 /// alias the pointer. Return the unified set, or nullptr if no set that aliases 269 /// the pointer was found. MustAliasAll is updated to true/false if the pointer 270 /// is found to MustAlias all the sets it merged. 271 AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr, 272 LocationSize Size, 273 const AAMDNodes &AAInfo, 274 bool &MustAliasAll) { 275 AliasSet *FoundSet = nullptr; 276 MustAliasAll = true; 277 BatchAAResults BatchAA(AA); 278 for (AliasSet &AS : llvm::make_early_inc_range(*this)) { 279 if (AS.Forward) 280 continue; 281 282 AliasResult AR = AS.aliasesPointer(Ptr, Size, AAInfo, BatchAA); 283 if (AR == AliasResult::NoAlias) 284 continue; 285 286 if (AR != AliasResult::MustAlias) 287 MustAliasAll = false; 288 289 if (!FoundSet) { 290 // If this is the first alias set ptr can go into, remember it. 291 FoundSet = &AS; 292 } else { 293 // Otherwise, we must merge the sets. 294 FoundSet->mergeSetIn(AS, *this, BatchAA); 295 } 296 } 297 298 return FoundSet; 299 } 300 301 AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) { 302 BatchAAResults BatchAA(AA); 303 AliasSet *FoundSet = nullptr; 304 for (AliasSet &AS : llvm::make_early_inc_range(*this)) { 305 if (AS.Forward || !AS.aliasesUnknownInst(Inst, BatchAA)) 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, BatchAA); 313 } 314 } 315 return FoundSet; 316 } 317 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 369 void AliasSetTracker::add(Value *Ptr, LocationSize Size, 370 const AAMDNodes &AAInfo) { 371 addPointer(MemoryLocation(Ptr, Size, AAInfo), AliasSet::NoAccess); 372 } 373 374 void AliasSetTracker::add(LoadInst *LI) { 375 if (isStrongerThanMonotonic(LI->getOrdering())) 376 return addUnknown(LI); 377 addPointer(MemoryLocation::get(LI), AliasSet::RefAccess); 378 } 379 380 void AliasSetTracker::add(StoreInst *SI) { 381 if (isStrongerThanMonotonic(SI->getOrdering())) 382 return addUnknown(SI); 383 addPointer(MemoryLocation::get(SI), AliasSet::ModAccess); 384 } 385 386 void AliasSetTracker::add(VAArgInst *VAAI) { 387 addPointer(MemoryLocation::get(VAAI), AliasSet::ModRefAccess); 388 } 389 390 void AliasSetTracker::add(AnyMemSetInst *MSI) { 391 addPointer(MemoryLocation::getForDest(MSI), AliasSet::ModAccess); 392 } 393 394 void AliasSetTracker::add(AnyMemTransferInst *MTI) { 395 addPointer(MemoryLocation::getForDest(MTI), AliasSet::ModAccess); 396 addPointer(MemoryLocation::getForSource(MTI), AliasSet::RefAccess); 397 } 398 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 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.getModRefBehavior(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 483 void AliasSetTracker::add(BasicBlock &BB) { 484 for (auto &I : BB) 485 add(&I); 486 } 487 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 (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i) 501 if (auto *Inst = AS.getUnknownInst(i)) 502 add(Inst); 503 504 // Loop over all of the pointers in this alias set. 505 for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) 506 addPointer( 507 MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()), 508 (AliasSet::AccessLattice)AS.Access); 509 } 510 } 511 512 // deleteValue method - This method is used to remove a pointer value from the 513 // AliasSetTracker entirely. It should be used when an instruction is deleted 514 // from the program to update the AST. If you don't use this, you would have 515 // dangling pointers to deleted instructions. 516 // 517 void AliasSetTracker::deleteValue(Value *PtrVal) { 518 // First, look up the PointerRec for this pointer. 519 PointerMapType::iterator I = PointerMap.find_as(PtrVal); 520 if (I == PointerMap.end()) return; // Noop 521 522 // If we found one, remove the pointer from the alias set it is in. 523 AliasSet::PointerRec *PtrValEnt = I->second; 524 AliasSet *AS = PtrValEnt->getAliasSet(*this); 525 526 // Unlink and delete from the list of values. 527 PtrValEnt->eraseFromList(); 528 529 if (AS->Alias == AliasSet::SetMayAlias) { 530 AS->SetSize--; 531 TotalMayAliasSetSize--; 532 } 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 // 545 void 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 // getEntryFor above may invalidate iterator \c I, so reinitialize it. 556 I = PointerMap.find_as(From); 557 // Add it to the alias set it aliases... 558 AliasSet *AS = I->second->getAliasSet(*this); 559 AS->addPointer(*this, Entry, I->second->getSize(), I->second->getAAInfo(), 560 true, true); 561 } 562 563 AliasSet &AliasSetTracker::mergeAllAliasSets() { 564 assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) && 565 "Full merge should happen once, when the saturation threshold is " 566 "reached"); 567 568 // Collect all alias sets, so that we can drop references with impunity 569 // without worrying about iterator invalidation. 570 std::vector<AliasSet *> ASVector; 571 ASVector.reserve(SaturationThreshold); 572 for (AliasSet &AS : *this) 573 ASVector.push_back(&AS); 574 575 // Copy all instructions and pointers into a new set, and forward all other 576 // sets to it. 577 AliasSets.push_back(new AliasSet()); 578 AliasAnyAS = &AliasSets.back(); 579 AliasAnyAS->Alias = AliasSet::SetMayAlias; 580 AliasAnyAS->Access = AliasSet::ModRefAccess; 581 AliasAnyAS->AliasAny = true; 582 583 BatchAAResults BatchAA(AA); 584 for (auto *Cur : ASVector) { 585 // If Cur was already forwarding, just forward to the new AS instead. 586 AliasSet *FwdTo = Cur->Forward; 587 if (FwdTo) { 588 Cur->Forward = AliasAnyAS; 589 AliasAnyAS->addRef(); 590 FwdTo->dropRef(*this); 591 continue; 592 } 593 594 // Otherwise, perform the actual merge. 595 AliasAnyAS->mergeSetIn(*Cur, *this, BatchAA); 596 } 597 598 return *AliasAnyAS; 599 } 600 601 AliasSet &AliasSetTracker::addPointer(MemoryLocation Loc, 602 AliasSet::AccessLattice E) { 603 AliasSet &AS = getAliasSetFor(Loc); 604 AS.Access |= E; 605 606 if (!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold)) { 607 // The AST is now saturated. From here on, we conservatively consider all 608 // pointers to alias each-other. 609 return mergeAllAliasSets(); 610 } 611 612 return AS; 613 } 614 615 //===----------------------------------------------------------------------===// 616 // AliasSet/AliasSetTracker Printing Support 617 //===----------------------------------------------------------------------===// 618 619 void AliasSet::print(raw_ostream &OS) const { 620 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] "; 621 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, "; 622 switch (Access) { 623 case NoAccess: OS << "No access "; break; 624 case RefAccess: OS << "Ref "; break; 625 case ModAccess: OS << "Mod "; break; 626 case ModRefAccess: OS << "Mod/Ref "; break; 627 default: llvm_unreachable("Bad value for Access!"); 628 } 629 if (Forward) 630 OS << " forwarding to " << (void*)Forward; 631 632 if (!empty()) { 633 OS << "Pointers: "; 634 for (iterator I = begin(), E = end(); I != E; ++I) { 635 if (I != begin()) OS << ", "; 636 I.getPointer()->printAsOperand(OS << "("); 637 if (I.getSize() == LocationSize::afterPointer()) 638 OS << ", unknown after)"; 639 else if (I.getSize() == LocationSize::beforeOrAfterPointer()) 640 OS << ", unknown before-or-after)"; 641 else 642 OS << ", " << I.getSize() << ")"; 643 } 644 } 645 if (!UnknownInsts.empty()) { 646 OS << "\n " << UnknownInsts.size() << " Unknown instructions: "; 647 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { 648 if (i) OS << ", "; 649 if (auto *I = getUnknownInst(i)) { 650 if (I->hasName()) 651 I->printAsOperand(OS); 652 else 653 I->print(OS); 654 } 655 } 656 } 657 OS << "\n"; 658 } 659 660 void AliasSetTracker::print(raw_ostream &OS) const { 661 OS << "Alias Set Tracker: " << AliasSets.size(); 662 if (AliasAnyAS) 663 OS << " (Saturated)"; 664 OS << " alias sets for " << PointerMap.size() << " pointer values.\n"; 665 for (const AliasSet &AS : *this) 666 AS.print(OS); 667 OS << "\n"; 668 } 669 670 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 671 LLVM_DUMP_METHOD void AliasSet::dump() const { print(dbgs()); } 672 LLVM_DUMP_METHOD void AliasSetTracker::dump() const { print(dbgs()); } 673 #endif 674 675 //===----------------------------------------------------------------------===// 676 // ASTCallbackVH Class Implementation 677 //===----------------------------------------------------------------------===// 678 679 void AliasSetTracker::ASTCallbackVH::deleted() { 680 assert(AST && "ASTCallbackVH called with a null AliasSetTracker!"); 681 AST->deleteValue(getValPtr()); 682 // this now dangles! 683 } 684 685 void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) { 686 AST->copyValue(getValPtr(), V); 687 } 688 689 AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast) 690 : CallbackVH(V), AST(ast) {} 691 692 AliasSetTracker::ASTCallbackVH & 693 AliasSetTracker::ASTCallbackVH::operator=(Value *V) { 694 return *this = ASTCallbackVH(V, AST); 695 } 696 697 //===----------------------------------------------------------------------===// 698 // AliasSetPrinter Pass 699 //===----------------------------------------------------------------------===// 700 701 namespace { 702 703 class AliasSetPrinter : public FunctionPass { 704 public: 705 static char ID; // Pass identification, replacement for typeid 706 707 AliasSetPrinter() : FunctionPass(ID) { 708 initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry()); 709 } 710 711 void getAnalysisUsage(AnalysisUsage &AU) const override { 712 AU.setPreservesAll(); 713 AU.addRequired<AAResultsWrapperPass>(); 714 } 715 716 bool runOnFunction(Function &F) override { 717 auto &AAWP = getAnalysis<AAResultsWrapperPass>(); 718 AliasSetTracker Tracker(AAWP.getAAResults()); 719 errs() << "Alias sets for function '" << F.getName() << "':\n"; 720 for (Instruction &I : instructions(F)) 721 Tracker.add(&I); 722 Tracker.print(errs()); 723 return false; 724 } 725 }; 726 727 } // end anonymous namespace 728 729 char AliasSetPrinter::ID = 0; 730 731 INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets", 732 "Alias Set Printer", false, true) 733 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 734 INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets", 735 "Alias Set Printer", false, true) 736 737 AliasSetsPrinterPass::AliasSetsPrinterPass(raw_ostream &OS) : OS(OS) {} 738 739 PreservedAnalyses AliasSetsPrinterPass::run(Function &F, 740 FunctionAnalysisManager &AM) { 741 auto &AA = AM.getResult<AAManager>(F); 742 AliasSetTracker Tracker(AA); 743 OS << "Alias sets for function '" << F.getName() << "':\n"; 744 for (Instruction &I : instructions(F)) 745 Tracker.add(&I); 746 Tracker.print(OS); 747 return PreservedAnalyses::all(); 748 } 749