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