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