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/GuardUtils.h" 15 #include "llvm/Analysis/LoopInfo.h" 16 #include "llvm/Analysis/MemoryLocation.h" 17 #include "llvm/Config/llvm-config.h" 18 #include "llvm/IR/Constants.h" 19 #include "llvm/IR/DataLayout.h" 20 #include "llvm/IR/Function.h" 21 #include "llvm/IR/InstIterator.h" 22 #include "llvm/IR/Instructions.h" 23 #include "llvm/IR/IntrinsicInst.h" 24 #include "llvm/IR/Module.h" 25 #include "llvm/IR/PassManager.h" 26 #include "llvm/IR/PatternMatch.h" 27 #include "llvm/IR/Value.h" 28 #include "llvm/InitializePasses.h" 29 #include "llvm/Pass.h" 30 #include "llvm/Support/AtomicOrdering.h" 31 #include "llvm/Support/CommandLine.h" 32 #include "llvm/Support/Compiler.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/raw_ostream.h" 36 37 using namespace llvm; 38 39 static cl::opt<unsigned> 40 SaturationThreshold("alias-set-saturation-threshold", cl::Hidden, 41 cl::init(250), 42 cl::desc("The maximum number of pointers may-alias " 43 "sets may contain before degradation")); 44 45 /// mergeSetIn - Merge the specified alias set into this alias set. 46 /// 47 void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) { 48 assert(!AS.Forward && "Alias set is already forwarding!"); 49 assert(!Forward && "This set is a forwarding set!!"); 50 51 bool WasMustAlias = (Alias == SetMustAlias); 52 // Update the alias and access types of this set... 53 Access |= AS.Access; 54 Alias |= AS.Alias; 55 56 if (Alias == SetMustAlias) { 57 // Check that these two merged sets really are must aliases. Since both 58 // used to be must-alias sets, we can just check any pointer from each set 59 // for aliasing. 60 AliasAnalysis &AA = AST.getAliasAnalysis(); 61 PointerRec *L = getSomePointer(); 62 PointerRec *R = AS.getSomePointer(); 63 64 // If the pointers are not a must-alias pair, this set becomes a may alias. 65 if (AA.alias(MemoryLocation(L->getValue(), L->getSize(), L->getAAInfo()), 66 MemoryLocation(R->getValue(), R->getSize(), R->getAAInfo())) != 67 MustAlias) 68 Alias = SetMayAlias; 69 } 70 71 if (Alias == SetMayAlias) { 72 if (WasMustAlias) 73 AST.TotalMayAliasSetSize += size(); 74 if (AS.Alias == SetMustAlias) 75 AST.TotalMayAliasSetSize += AS.size(); 76 } 77 78 bool ASHadUnknownInsts = !AS.UnknownInsts.empty(); 79 if (UnknownInsts.empty()) { // Merge call sites... 80 if (ASHadUnknownInsts) { 81 std::swap(UnknownInsts, AS.UnknownInsts); 82 addRef(); 83 } 84 } else if (ASHadUnknownInsts) { 85 llvm::append_range(UnknownInsts, AS.UnknownInsts); 86 AS.UnknownInsts.clear(); 87 } 88 89 AS.Forward = this; // Forward across AS now... 90 addRef(); // AS is now pointing to us... 91 92 // Merge the list of constituent pointers... 93 if (AS.PtrList) { 94 SetSize += AS.size(); 95 AS.SetSize = 0; 96 *PtrListEnd = AS.PtrList; 97 AS.PtrList->setPrevInList(PtrListEnd); 98 PtrListEnd = AS.PtrListEnd; 99 100 AS.PtrList = nullptr; 101 AS.PtrListEnd = &AS.PtrList; 102 assert(*AS.PtrListEnd == nullptr && "End of list is not null?"); 103 } 104 if (ASHadUnknownInsts) 105 AS.dropRef(AST); 106 } 107 108 void AliasSetTracker::removeAliasSet(AliasSet *AS) { 109 if (AliasSet *Fwd = AS->Forward) { 110 Fwd->dropRef(*this); 111 AS->Forward = nullptr; 112 } else // Update TotalMayAliasSetSize only if not forwarding. 113 if (AS->Alias == AliasSet::SetMayAlias) 114 TotalMayAliasSetSize -= AS->size(); 115 116 AliasSets.erase(AS); 117 // If we've removed the saturated alias set, set saturated marker back to 118 // nullptr and ensure this tracker is empty. 119 if (AS == AliasAnyAS) { 120 AliasAnyAS = nullptr; 121 assert(AliasSets.empty() && "Tracker not empty"); 122 } 123 } 124 125 void AliasSet::removeFromTracker(AliasSetTracker &AST) { 126 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!"); 127 AST.removeAliasSet(this); 128 } 129 130 void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry, 131 LocationSize Size, const AAMDNodes &AAInfo, 132 bool KnownMustAlias, bool SkipSizeUpdate) { 133 assert(!Entry.hasAliasSet() && "Entry already in set!"); 134 135 // Check to see if we have to downgrade to _may_ alias. 136 if (isMustAlias()) 137 if (PointerRec *P = getSomePointer()) { 138 if (!KnownMustAlias) { 139 AliasAnalysis &AA = AST.getAliasAnalysis(); 140 AliasResult Result = AA.alias( 141 MemoryLocation(P->getValue(), P->getSize(), P->getAAInfo()), 142 MemoryLocation(Entry.getValue(), Size, AAInfo)); 143 if (Result != MustAlias) { 144 Alias = SetMayAlias; 145 AST.TotalMayAliasSetSize += size(); 146 } 147 assert(Result != NoAlias && "Cannot be part of must set!"); 148 } else if (!SkipSizeUpdate) 149 P->updateSizeAndAAInfo(Size, AAInfo); 150 } 151 152 Entry.setAliasSet(this); 153 Entry.updateSizeAndAAInfo(Size, AAInfo); 154 155 // Add it to the end of the list... 156 ++SetSize; 157 assert(*PtrListEnd == nullptr && "End of list is not null?"); 158 *PtrListEnd = &Entry; 159 PtrListEnd = Entry.setPrevInList(PtrListEnd); 160 assert(*PtrListEnd == nullptr && "End of list is not null?"); 161 // Entry points to alias set. 162 addRef(); 163 164 if (Alias == SetMayAlias) 165 AST.TotalMayAliasSetSize++; 166 } 167 168 void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) { 169 if (UnknownInsts.empty()) 170 addRef(); 171 UnknownInsts.emplace_back(I); 172 173 // Guards are marked as modifying memory for control flow modelling purposes, 174 // but don't actually modify any specific memory location. 175 using namespace PatternMatch; 176 bool MayWriteMemory = I->mayWriteToMemory() && !isGuard(I) && 177 !(I->use_empty() && match(I, m_Intrinsic<Intrinsic::invariant_start>())); 178 if (!MayWriteMemory) { 179 Alias = SetMayAlias; 180 Access |= RefAccess; 181 return; 182 } 183 184 // FIXME: This should use mod/ref information to make this not suck so bad 185 Alias = SetMayAlias; 186 Access = ModRefAccess; 187 } 188 189 /// aliasesPointer - If the specified pointer "may" (or must) alias one of the 190 /// members in the set return the appropriate AliasResult. Otherwise return 191 /// NoAlias. 192 /// 193 AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size, 194 const AAMDNodes &AAInfo, 195 AliasAnalysis &AA) const { 196 if (AliasAny) 197 return MayAlias; 198 199 if (Alias == SetMustAlias) { 200 assert(UnknownInsts.empty() && "Illegal must alias set!"); 201 202 // If this is a set of MustAliases, only check to see if the pointer aliases 203 // SOME value in the set. 204 PointerRec *SomePtr = getSomePointer(); 205 assert(SomePtr && "Empty must-alias set??"); 206 return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(), 207 SomePtr->getAAInfo()), 208 MemoryLocation(Ptr, Size, AAInfo)); 209 } 210 211 // If this is a may-alias set, we have to check all of the pointers in the set 212 // to be sure it doesn't alias the set... 213 for (iterator I = begin(), E = end(); I != E; ++I) 214 if (AliasResult AR = AA.alias( 215 MemoryLocation(Ptr, Size, AAInfo), 216 MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))) 217 return AR; 218 219 // Check the unknown instructions... 220 if (!UnknownInsts.empty()) { 221 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) 222 if (auto *Inst = getUnknownInst(i)) 223 if (isModOrRefSet( 224 AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)))) 225 return MayAlias; 226 } 227 228 return NoAlias; 229 } 230 231 bool AliasSet::aliasesUnknownInst(const Instruction *Inst, 232 AliasAnalysis &AA) const { 233 234 if (AliasAny) 235 return true; 236 237 assert(Inst->mayReadOrWriteMemory() && 238 "Instruction must either read or write memory."); 239 240 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { 241 if (auto *UnknownInst = getUnknownInst(i)) { 242 const auto *C1 = dyn_cast<CallBase>(UnknownInst); 243 const auto *C2 = dyn_cast<CallBase>(Inst); 244 if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) || 245 isModOrRefSet(AA.getModRefInfo(C2, C1))) 246 return true; 247 } 248 } 249 250 for (iterator I = begin(), E = end(); I != E; ++I) 251 if (isModOrRefSet(AA.getModRefInfo( 252 Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))) 253 return true; 254 255 return false; 256 } 257 258 Instruction* AliasSet::getUniqueInstruction() { 259 if (AliasAny) 260 // May have collapses alias set 261 return nullptr; 262 if (begin() != end()) { 263 if (!UnknownInsts.empty()) 264 // Another instruction found 265 return nullptr; 266 if (std::next(begin()) != end()) 267 // Another instruction found 268 return nullptr; 269 Value *Addr = begin()->getValue(); 270 assert(!Addr->user_empty() && 271 "where's the instruction which added this pointer?"); 272 if (std::next(Addr->user_begin()) != Addr->user_end()) 273 // Another instruction found -- this is really restrictive 274 // TODO: generalize! 275 return nullptr; 276 return cast<Instruction>(*(Addr->user_begin())); 277 } 278 if (1 != UnknownInsts.size()) 279 return nullptr; 280 return cast<Instruction>(UnknownInsts[0]); 281 } 282 283 void AliasSetTracker::clear() { 284 // Delete all the PointerRec entries. 285 for (auto &I : PointerMap) 286 I.second->eraseFromList(); 287 288 PointerMap.clear(); 289 290 // The alias sets should all be clear now. 291 AliasSets.clear(); 292 } 293 294 /// mergeAliasSetsForPointer - Given a pointer, merge all alias sets that may 295 /// alias the pointer. Return the unified set, or nullptr if no set that aliases 296 /// the pointer was found. MustAliasAll is updated to true/false if the pointer 297 /// is found to MustAlias all the sets it merged. 298 AliasSet *AliasSetTracker::mergeAliasSetsForPointer(const Value *Ptr, 299 LocationSize Size, 300 const AAMDNodes &AAInfo, 301 bool &MustAliasAll) { 302 AliasSet *FoundSet = nullptr; 303 MustAliasAll = true; 304 for (AliasSet &AS : llvm::make_early_inc_range(*this)) { 305 if (AS.Forward) 306 continue; 307 308 AliasResult AR = AS.aliasesPointer(Ptr, Size, AAInfo, AA); 309 if (AR == NoAlias) 310 continue; 311 312 if (AR != MustAlias) 313 MustAliasAll = false; 314 315 if (!FoundSet) { 316 // If this is the first alias set ptr can go into, remember it. 317 FoundSet = &AS; 318 } else { 319 // Otherwise, we must merge the sets. 320 FoundSet->mergeSetIn(AS, *this); 321 } 322 } 323 324 return FoundSet; 325 } 326 327 AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) { 328 AliasSet *FoundSet = nullptr; 329 for (AliasSet &AS : llvm::make_early_inc_range(*this)) { 330 if (AS.Forward || !AS.aliasesUnknownInst(Inst, AA)) 331 continue; 332 if (!FoundSet) { 333 // If this is the first alias set ptr can go into, remember it. 334 FoundSet = &AS; 335 } else { 336 // Otherwise, we must merge the sets. 337 FoundSet->mergeSetIn(AS, *this); 338 } 339 } 340 return FoundSet; 341 } 342 343 AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) { 344 345 Value * const Pointer = const_cast<Value*>(MemLoc.Ptr); 346 const LocationSize Size = MemLoc.Size; 347 const AAMDNodes &AAInfo = MemLoc.AATags; 348 349 AliasSet::PointerRec &Entry = getEntryFor(Pointer); 350 351 if (AliasAnyAS) { 352 // At this point, the AST is saturated, so we only have one active alias 353 // set. That means we already know which alias set we want to return, and 354 // just need to add the pointer to that set to keep the data structure 355 // consistent. 356 // This, of course, means that we will never need a merge here. 357 if (Entry.hasAliasSet()) { 358 Entry.updateSizeAndAAInfo(Size, AAInfo); 359 assert(Entry.getAliasSet(*this) == AliasAnyAS && 360 "Entry in saturated AST must belong to only alias set"); 361 } else { 362 AliasAnyAS->addPointer(*this, Entry, Size, AAInfo); 363 } 364 return *AliasAnyAS; 365 } 366 367 bool MustAliasAll = false; 368 // Check to see if the pointer is already known. 369 if (Entry.hasAliasSet()) { 370 // If the size changed, we may need to merge several alias sets. 371 // Note that we can *not* return the result of mergeAliasSetsForPointer 372 // due to a quirk of alias analysis behavior. Since alias(undef, undef) 373 // is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the 374 // the right set for undef, even if it exists. 375 if (Entry.updateSizeAndAAInfo(Size, AAInfo)) 376 mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll); 377 // Return the set! 378 return *Entry.getAliasSet(*this)->getForwardedTarget(*this); 379 } 380 381 if (AliasSet *AS = 382 mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll)) { 383 // Add it to the alias set it aliases. 384 AS->addPointer(*this, Entry, Size, AAInfo, MustAliasAll); 385 return *AS; 386 } 387 388 // Otherwise create a new alias set to hold the loaded pointer. 389 AliasSets.push_back(new AliasSet()); 390 AliasSets.back().addPointer(*this, Entry, Size, AAInfo, true); 391 return AliasSets.back(); 392 } 393 394 void AliasSetTracker::add(Value *Ptr, LocationSize Size, 395 const AAMDNodes &AAInfo) { 396 addPointer(MemoryLocation(Ptr, Size, AAInfo), AliasSet::NoAccess); 397 } 398 399 void AliasSetTracker::add(LoadInst *LI) { 400 if (isStrongerThanMonotonic(LI->getOrdering())) 401 return addUnknown(LI); 402 addPointer(MemoryLocation::get(LI), AliasSet::RefAccess); 403 } 404 405 void AliasSetTracker::add(StoreInst *SI) { 406 if (isStrongerThanMonotonic(SI->getOrdering())) 407 return addUnknown(SI); 408 addPointer(MemoryLocation::get(SI), AliasSet::ModAccess); 409 } 410 411 void AliasSetTracker::add(VAArgInst *VAAI) { 412 addPointer(MemoryLocation::get(VAAI), AliasSet::ModRefAccess); 413 } 414 415 void AliasSetTracker::add(AnyMemSetInst *MSI) { 416 addPointer(MemoryLocation::getForDest(MSI), AliasSet::ModAccess); 417 } 418 419 void AliasSetTracker::add(AnyMemTransferInst *MTI) { 420 addPointer(MemoryLocation::getForDest(MTI), AliasSet::ModAccess); 421 addPointer(MemoryLocation::getForSource(MTI), AliasSet::RefAccess); 422 } 423 424 void AliasSetTracker::addUnknown(Instruction *Inst) { 425 if (isa<DbgInfoIntrinsic>(Inst)) 426 return; // Ignore DbgInfo Intrinsics. 427 428 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) { 429 // These intrinsics will show up as affecting memory, but they are just 430 // markers. 431 switch (II->getIntrinsicID()) { 432 default: 433 break; 434 // FIXME: Add lifetime/invariant intrinsics (See: PR30807). 435 case Intrinsic::assume: 436 case Intrinsic::experimental_noalias_scope_decl: 437 case Intrinsic::sideeffect: 438 case Intrinsic::pseudoprobe: 439 return; 440 } 441 } 442 if (!Inst->mayReadOrWriteMemory()) 443 return; // doesn't alias anything 444 445 if (AliasSet *AS = findAliasSetForUnknownInst(Inst)) { 446 AS->addUnknownInst(Inst, AA); 447 return; 448 } 449 AliasSets.push_back(new AliasSet()); 450 AliasSets.back().addUnknownInst(Inst, AA); 451 } 452 453 void AliasSetTracker::add(Instruction *I) { 454 // Dispatch to one of the other add methods. 455 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 456 return add(LI); 457 if (StoreInst *SI = dyn_cast<StoreInst>(I)) 458 return add(SI); 459 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I)) 460 return add(VAAI); 461 if (AnyMemSetInst *MSI = dyn_cast<AnyMemSetInst>(I)) 462 return add(MSI); 463 if (AnyMemTransferInst *MTI = dyn_cast<AnyMemTransferInst>(I)) 464 return add(MTI); 465 466 // Handle all calls with known mod/ref sets genericall 467 if (auto *Call = dyn_cast<CallBase>(I)) 468 if (Call->onlyAccessesArgMemory()) { 469 auto getAccessFromModRef = [](ModRefInfo MRI) { 470 if (isRefSet(MRI) && isModSet(MRI)) 471 return AliasSet::ModRefAccess; 472 else if (isModSet(MRI)) 473 return AliasSet::ModAccess; 474 else if (isRefSet(MRI)) 475 return AliasSet::RefAccess; 476 else 477 return AliasSet::NoAccess; 478 }; 479 480 ModRefInfo CallMask = createModRefInfo(AA.getModRefBehavior(Call)); 481 482 // Some intrinsics are marked as modifying memory for control flow 483 // modelling purposes, but don't actually modify any specific memory 484 // location. 485 using namespace PatternMatch; 486 if (Call->use_empty() && 487 match(Call, m_Intrinsic<Intrinsic::invariant_start>())) 488 CallMask = clearMod(CallMask); 489 490 for (auto IdxArgPair : enumerate(Call->args())) { 491 int ArgIdx = IdxArgPair.index(); 492 const Value *Arg = IdxArgPair.value(); 493 if (!Arg->getType()->isPointerTy()) 494 continue; 495 MemoryLocation ArgLoc = 496 MemoryLocation::getForArgument(Call, ArgIdx, nullptr); 497 ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx); 498 ArgMask = intersectModRef(CallMask, ArgMask); 499 if (!isNoModRef(ArgMask)) 500 addPointer(ArgLoc, getAccessFromModRef(ArgMask)); 501 } 502 return; 503 } 504 505 return addUnknown(I); 506 } 507 508 void AliasSetTracker::add(BasicBlock &BB) { 509 for (auto &I : BB) 510 add(&I); 511 } 512 513 void AliasSetTracker::add(const AliasSetTracker &AST) { 514 assert(&AA == &AST.AA && 515 "Merging AliasSetTracker objects with different Alias Analyses!"); 516 517 // Loop over all of the alias sets in AST, adding the pointers contained 518 // therein into the current alias sets. This can cause alias sets to be 519 // merged together in the current AST. 520 for (const AliasSet &AS : AST) { 521 if (AS.Forward) 522 continue; // Ignore forwarding alias sets 523 524 // If there are any call sites in the alias set, add them to this AST. 525 for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i) 526 if (auto *Inst = AS.getUnknownInst(i)) 527 add(Inst); 528 529 // Loop over all of the pointers in this alias set. 530 for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) 531 addPointer( 532 MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()), 533 (AliasSet::AccessLattice)AS.Access); 534 } 535 } 536 537 // deleteValue method - This method is used to remove a pointer value from the 538 // AliasSetTracker entirely. It should be used when an instruction is deleted 539 // from the program to update the AST. If you don't use this, you would have 540 // dangling pointers to deleted instructions. 541 // 542 void AliasSetTracker::deleteValue(Value *PtrVal) { 543 // First, look up the PointerRec for this pointer. 544 PointerMapType::iterator I = PointerMap.find_as(PtrVal); 545 if (I == PointerMap.end()) return; // Noop 546 547 // If we found one, remove the pointer from the alias set it is in. 548 AliasSet::PointerRec *PtrValEnt = I->second; 549 AliasSet *AS = PtrValEnt->getAliasSet(*this); 550 551 // Unlink and delete from the list of values. 552 PtrValEnt->eraseFromList(); 553 554 if (AS->Alias == AliasSet::SetMayAlias) { 555 AS->SetSize--; 556 TotalMayAliasSetSize--; 557 } 558 559 // Stop using the alias set. 560 AS->dropRef(*this); 561 562 PointerMap.erase(I); 563 } 564 565 // copyValue - This method should be used whenever a preexisting value in the 566 // program is copied or cloned, introducing a new value. Note that it is ok for 567 // clients that use this method to introduce the same value multiple times: if 568 // the tracker already knows about a value, it will ignore the request. 569 // 570 void AliasSetTracker::copyValue(Value *From, Value *To) { 571 // First, look up the PointerRec for this pointer. 572 PointerMapType::iterator I = PointerMap.find_as(From); 573 if (I == PointerMap.end()) 574 return; // Noop 575 assert(I->second->hasAliasSet() && "Dead entry?"); 576 577 AliasSet::PointerRec &Entry = getEntryFor(To); 578 if (Entry.hasAliasSet()) return; // Already in the tracker! 579 580 // getEntryFor above may invalidate iterator \c I, so reinitialize it. 581 I = PointerMap.find_as(From); 582 // Add it to the alias set it aliases... 583 AliasSet *AS = I->second->getAliasSet(*this); 584 AS->addPointer(*this, Entry, I->second->getSize(), I->second->getAAInfo(), 585 true, true); 586 } 587 588 AliasSet &AliasSetTracker::mergeAllAliasSets() { 589 assert(!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold) && 590 "Full merge should happen once, when the saturation threshold is " 591 "reached"); 592 593 // Collect all alias sets, so that we can drop references with impunity 594 // without worrying about iterator invalidation. 595 std::vector<AliasSet *> ASVector; 596 ASVector.reserve(SaturationThreshold); 597 for (AliasSet &AS : *this) 598 ASVector.push_back(&AS); 599 600 // Copy all instructions and pointers into a new set, and forward all other 601 // sets to it. 602 AliasSets.push_back(new AliasSet()); 603 AliasAnyAS = &AliasSets.back(); 604 AliasAnyAS->Alias = AliasSet::SetMayAlias; 605 AliasAnyAS->Access = AliasSet::ModRefAccess; 606 AliasAnyAS->AliasAny = true; 607 608 for (auto Cur : ASVector) { 609 // If Cur was already forwarding, just forward to the new AS instead. 610 AliasSet *FwdTo = Cur->Forward; 611 if (FwdTo) { 612 Cur->Forward = AliasAnyAS; 613 AliasAnyAS->addRef(); 614 FwdTo->dropRef(*this); 615 continue; 616 } 617 618 // Otherwise, perform the actual merge. 619 AliasAnyAS->mergeSetIn(*Cur, *this); 620 } 621 622 return *AliasAnyAS; 623 } 624 625 AliasSet &AliasSetTracker::addPointer(MemoryLocation Loc, 626 AliasSet::AccessLattice E) { 627 AliasSet &AS = getAliasSetFor(Loc); 628 AS.Access |= E; 629 630 if (!AliasAnyAS && (TotalMayAliasSetSize > SaturationThreshold)) { 631 // The AST is now saturated. From here on, we conservatively consider all 632 // pointers to alias each-other. 633 return mergeAllAliasSets(); 634 } 635 636 return AS; 637 } 638 639 //===----------------------------------------------------------------------===// 640 // AliasSet/AliasSetTracker Printing Support 641 //===----------------------------------------------------------------------===// 642 643 void AliasSet::print(raw_ostream &OS) const { 644 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] "; 645 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, "; 646 switch (Access) { 647 case NoAccess: OS << "No access "; break; 648 case RefAccess: OS << "Ref "; break; 649 case ModAccess: OS << "Mod "; break; 650 case ModRefAccess: OS << "Mod/Ref "; break; 651 default: llvm_unreachable("Bad value for Access!"); 652 } 653 if (Forward) 654 OS << " forwarding to " << (void*)Forward; 655 656 if (!empty()) { 657 OS << "Pointers: "; 658 for (iterator I = begin(), E = end(); I != E; ++I) { 659 if (I != begin()) OS << ", "; 660 I.getPointer()->printAsOperand(OS << "("); 661 if (I.getSize() == LocationSize::afterPointer()) 662 OS << ", unknown after)"; 663 else if (I.getSize() == LocationSize::beforeOrAfterPointer()) 664 OS << ", unknown before-or-after)"; 665 else 666 OS << ", " << I.getSize() << ")"; 667 } 668 } 669 if (!UnknownInsts.empty()) { 670 OS << "\n " << UnknownInsts.size() << " Unknown instructions: "; 671 for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { 672 if (i) OS << ", "; 673 if (auto *I = getUnknownInst(i)) { 674 if (I->hasName()) 675 I->printAsOperand(OS); 676 else 677 I->print(OS); 678 } 679 } 680 } 681 OS << "\n"; 682 } 683 684 void AliasSetTracker::print(raw_ostream &OS) const { 685 OS << "Alias Set Tracker: " << AliasSets.size(); 686 if (AliasAnyAS) 687 OS << " (Saturated)"; 688 OS << " alias sets for " << PointerMap.size() << " pointer values.\n"; 689 for (const AliasSet &AS : *this) 690 AS.print(OS); 691 OS << "\n"; 692 } 693 694 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 695 LLVM_DUMP_METHOD void AliasSet::dump() const { print(dbgs()); } 696 LLVM_DUMP_METHOD void AliasSetTracker::dump() const { print(dbgs()); } 697 #endif 698 699 //===----------------------------------------------------------------------===// 700 // ASTCallbackVH Class Implementation 701 //===----------------------------------------------------------------------===// 702 703 void AliasSetTracker::ASTCallbackVH::deleted() { 704 assert(AST && "ASTCallbackVH called with a null AliasSetTracker!"); 705 AST->deleteValue(getValPtr()); 706 // this now dangles! 707 } 708 709 void AliasSetTracker::ASTCallbackVH::allUsesReplacedWith(Value *V) { 710 AST->copyValue(getValPtr(), V); 711 } 712 713 AliasSetTracker::ASTCallbackVH::ASTCallbackVH(Value *V, AliasSetTracker *ast) 714 : CallbackVH(V), AST(ast) {} 715 716 AliasSetTracker::ASTCallbackVH & 717 AliasSetTracker::ASTCallbackVH::operator=(Value *V) { 718 return *this = ASTCallbackVH(V, AST); 719 } 720 721 //===----------------------------------------------------------------------===// 722 // AliasSetPrinter Pass 723 //===----------------------------------------------------------------------===// 724 725 namespace { 726 727 class AliasSetPrinter : public FunctionPass { 728 public: 729 static char ID; // Pass identification, replacement for typeid 730 731 AliasSetPrinter() : FunctionPass(ID) { 732 initializeAliasSetPrinterPass(*PassRegistry::getPassRegistry()); 733 } 734 735 void getAnalysisUsage(AnalysisUsage &AU) const override { 736 AU.setPreservesAll(); 737 AU.addRequired<AAResultsWrapperPass>(); 738 } 739 740 bool runOnFunction(Function &F) override { 741 auto &AAWP = getAnalysis<AAResultsWrapperPass>(); 742 AliasSetTracker Tracker(AAWP.getAAResults()); 743 errs() << "Alias sets for function '" << F.getName() << "':\n"; 744 for (Instruction &I : instructions(F)) 745 Tracker.add(&I); 746 Tracker.print(errs()); 747 return false; 748 } 749 }; 750 751 } // end anonymous namespace 752 753 char AliasSetPrinter::ID = 0; 754 755 INITIALIZE_PASS_BEGIN(AliasSetPrinter, "print-alias-sets", 756 "Alias Set Printer", false, true) 757 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 758 INITIALIZE_PASS_END(AliasSetPrinter, "print-alias-sets", 759 "Alias Set Printer", false, true) 760 761 AliasSetsPrinterPass::AliasSetsPrinterPass(raw_ostream &OS) : OS(OS) {} 762 763 PreservedAnalyses AliasSetsPrinterPass::run(Function &F, 764 FunctionAnalysisManager &AM) { 765 auto &AA = AM.getResult<AAManager>(F); 766 AliasSetTracker Tracker(AA); 767 OS << "Alias sets for function '" << F.getName() << "':\n"; 768 for (Instruction &I : instructions(F)) 769 Tracker.add(&I); 770 Tracker.print(OS); 771 return PreservedAnalyses::all(); 772 } 773