LLVM API Documentation
00001 //===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the AliasSetTracker and AliasSet classes. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Analysis/AliasSetTracker.h" 00015 #include "llvm/Analysis/AliasAnalysis.h" 00016 #include "llvm/Instructions.h" 00017 #include "llvm/Pass.h" 00018 #include "llvm/Type.h" 00019 #include "llvm/Target/TargetData.h" 00020 #include "llvm/Assembly/Writer.h" 00021 #include "llvm/Support/Compiler.h" 00022 #include "llvm/Support/InstIterator.h" 00023 #include "llvm/Support/Streams.h" 00024 using namespace llvm; 00025 00026 /// mergeSetIn - Merge the specified alias set into this alias set. 00027 /// 00028 void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) { 00029 assert(!AS.Forward && "Alias set is already forwarding!"); 00030 assert(!Forward && "This set is a forwarding set!!"); 00031 00032 // Update the alias and access types of this set... 00033 AccessTy |= AS.AccessTy; 00034 AliasTy |= AS.AliasTy; 00035 00036 if (AliasTy == MustAlias) { 00037 // Check that these two merged sets really are must aliases. Since both 00038 // used to be must-alias sets, we can just check any pointer from each set 00039 // for aliasing. 00040 AliasAnalysis &AA = AST.getAliasAnalysis(); 00041 HashNodePair *L = getSomePointer(); 00042 HashNodePair *R = AS.getSomePointer(); 00043 00044 // If the pointers are not a must-alias pair, this set becomes a may alias. 00045 if (AA.alias(L->first, L->second.getSize(), R->first, R->second.getSize()) 00046 != AliasAnalysis::MustAlias) 00047 AliasTy = MayAlias; 00048 } 00049 00050 if (CallSites.empty()) { // Merge call sites... 00051 if (!AS.CallSites.empty()) 00052 std::swap(CallSites, AS.CallSites); 00053 } else if (!AS.CallSites.empty()) { 00054 CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end()); 00055 AS.CallSites.clear(); 00056 } 00057 00058 AS.Forward = this; // Forward across AS now... 00059 addRef(); // AS is now pointing to us... 00060 00061 // Merge the list of constituent pointers... 00062 if (AS.PtrList) { 00063 *PtrListEnd = AS.PtrList; 00064 AS.PtrList->second.setPrevInList(PtrListEnd); 00065 PtrListEnd = AS.PtrListEnd; 00066 00067 AS.PtrList = 0; 00068 AS.PtrListEnd = &AS.PtrList; 00069 assert(*AS.PtrListEnd == 0 && "End of list is not null?"); 00070 } 00071 } 00072 00073 void AliasSetTracker::removeAliasSet(AliasSet *AS) { 00074 if (AliasSet *Fwd = AS->Forward) { 00075 Fwd->dropRef(*this); 00076 AS->Forward = 0; 00077 } 00078 AliasSets.erase(AS); 00079 } 00080 00081 void AliasSet::removeFromTracker(AliasSetTracker &AST) { 00082 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!"); 00083 AST.removeAliasSet(this); 00084 } 00085 00086 void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry, 00087 unsigned Size, bool KnownMustAlias) { 00088 assert(!Entry.second.hasAliasSet() && "Entry already in set!"); 00089 00090 // Check to see if we have to downgrade to _may_ alias. 00091 if (isMustAlias() && !KnownMustAlias) 00092 if (HashNodePair *P = getSomePointer()) { 00093 AliasAnalysis &AA = AST.getAliasAnalysis(); 00094 AliasAnalysis::AliasResult Result = 00095 AA.alias(P->first, P->second.getSize(), Entry.first, Size); 00096 if (Result == AliasAnalysis::MayAlias) 00097 AliasTy = MayAlias; 00098 else // First entry of must alias must have maximum size! 00099 P->second.updateSize(Size); 00100 assert(Result != AliasAnalysis::NoAlias && "Cannot be part of must set!"); 00101 } 00102 00103 Entry.second.setAliasSet(this); 00104 Entry.second.updateSize(Size); 00105 00106 // Add it to the end of the list... 00107 assert(*PtrListEnd == 0 && "End of list is not null?"); 00108 *PtrListEnd = &Entry; 00109 PtrListEnd = Entry.second.setPrevInList(PtrListEnd); 00110 assert(*PtrListEnd == 0 && "End of list is not null?"); 00111 addRef(); // Entry points to alias set... 00112 } 00113 00114 void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) { 00115 CallSites.push_back(CS); 00116 00117 AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS); 00118 if (Behavior == AliasAnalysis::DoesNotAccessMemory) 00119 return; 00120 else if (Behavior == AliasAnalysis::OnlyReadsMemory) { 00121 AliasTy = MayAlias; 00122 AccessTy |= Refs; 00123 return; 00124 } 00125 00126 // FIXME: This should use mod/ref information to make this not suck so bad 00127 AliasTy = MayAlias; 00128 AccessTy = ModRef; 00129 } 00130 00131 /// aliasesPointer - Return true if the specified pointer "may" (or must) 00132 /// alias one of the members in the set. 00133 /// 00134 bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size, 00135 AliasAnalysis &AA) const { 00136 if (AliasTy == MustAlias) { 00137 assert(CallSites.empty() && "Illegal must alias set!"); 00138 00139 // If this is a set of MustAliases, only check to see if the pointer aliases 00140 // SOME value in the set... 00141 HashNodePair *SomePtr = getSomePointer(); 00142 assert(SomePtr && "Empty must-alias set??"); 00143 return AA.alias(SomePtr->first, SomePtr->second.getSize(), Ptr, Size); 00144 } 00145 00146 // If this is a may-alias set, we have to check all of the pointers in the set 00147 // to be sure it doesn't alias the set... 00148 for (iterator I = begin(), E = end(); I != E; ++I) 00149 if (AA.alias(Ptr, Size, I.getPointer(), I.getSize())) 00150 return true; 00151 00152 // Check the call sites list and invoke list... 00153 if (!CallSites.empty()) { 00154 if (AA.hasNoModRefInfoForCalls()) 00155 return true; 00156 00157 for (unsigned i = 0, e = CallSites.size(); i != e; ++i) 00158 if (AA.getModRefInfo(CallSites[i], const_cast<Value*>(Ptr), Size) 00159 != AliasAnalysis::NoModRef) 00160 return true; 00161 } 00162 00163 return false; 00164 } 00165 00166 bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { 00167 if (AA.doesNotAccessMemory(CS)) 00168 return false; 00169 00170 if (AA.hasNoModRefInfoForCalls()) 00171 return true; 00172 00173 for (unsigned i = 0, e = CallSites.size(); i != e; ++i) 00174 if (AA.getModRefInfo(CallSites[i], CS) != AliasAnalysis::NoModRef || 00175 AA.getModRefInfo(CS, CallSites[i]) != AliasAnalysis::NoModRef) 00176 return true; 00177 00178 for (iterator I = begin(), E = end(); I != E; ++I) 00179 if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) != 00180 AliasAnalysis::NoModRef) 00181 return true; 00182 00183 return false; 00184 } 00185 00186 00187 /// findAliasSetForPointer - Given a pointer, find the one alias set to put the 00188 /// instruction referring to the pointer into. If there are multiple alias sets 00189 /// that may alias the pointer, merge them together and return the unified set. 00190 /// 00191 AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr, 00192 unsigned Size) { 00193 AliasSet *FoundSet = 0; 00194 for (iterator I = begin(), E = end(); I != E; ++I) 00195 if (!I->Forward && I->aliasesPointer(Ptr, Size, AA)) { 00196 if (FoundSet == 0) { // If this is the first alias set ptr can go into. 00197 FoundSet = I; // Remember it. 00198 } else { // Otherwise, we must merge the sets. 00199 FoundSet->mergeSetIn(*I, *this); // Merge in contents. 00200 } 00201 } 00202 00203 return FoundSet; 00204 } 00205 00206 /// containsPointer - Return true if the specified location is represented by 00207 /// this alias set, false otherwise. This does not modify the AST object or 00208 /// alias sets. 00209 bool AliasSetTracker::containsPointer(Value *Ptr, unsigned Size) const { 00210 for (const_iterator I = begin(), E = end(); I != E; ++I) 00211 if (!I->Forward && I->aliasesPointer(Ptr, Size, AA)) 00212 return true; 00213 return false; 00214 } 00215 00216 00217 00218 AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) { 00219 AliasSet *FoundSet = 0; 00220 for (iterator I = begin(), E = end(); I != E; ++I) 00221 if (!I->Forward && I->aliasesCallSite(CS, AA)) { 00222 if (FoundSet == 0) { // If this is the first alias set ptr can go into. 00223 FoundSet = I; // Remember it. 00224 } else if (!I->Forward) { // Otherwise, we must merge the sets. 00225 FoundSet->mergeSetIn(*I, *this); // Merge in contents. 00226 } 00227 } 00228 00229 return FoundSet; 00230 } 00231 00232 00233 00234 00235 /// getAliasSetForPointer - Return the alias set that the specified pointer 00236 /// lives in... 00237 AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, unsigned Size, 00238 bool *New) { 00239 AliasSet::HashNodePair &Entry = getEntryFor(Pointer); 00240 00241 // Check to see if the pointer is already known... 00242 if (Entry.second.hasAliasSet()) { 00243 Entry.second.updateSize(Size); 00244 // Return the set! 00245 return *Entry.second.getAliasSet(*this)->getForwardedTarget(*this); 00246 } else if (AliasSet *AS = findAliasSetForPointer(Pointer, Size)) { 00247 // Add it to the alias set it aliases... 00248 AS->addPointer(*this, Entry, Size); 00249 return *AS; 00250 } else { 00251 if (New) *New = true; 00252 // Otherwise create a new alias set to hold the loaded pointer... 00253 AliasSets.push_back(new AliasSet()); 00254 AliasSets.back().addPointer(*this, Entry, Size); 00255 return AliasSets.back(); 00256 } 00257 } 00258 00259 bool AliasSetTracker::add(Value *Ptr, unsigned Size) { 00260 bool NewPtr; 00261 addPointer(Ptr, Size, AliasSet::NoModRef, NewPtr); 00262 return NewPtr; 00263 } 00264 00265 00266 bool AliasSetTracker::add(LoadInst *LI) { 00267 bool NewPtr; 00268 AliasSet &AS = addPointer(LI->getOperand(0), 00269 AA.getTargetData().getTypeStoreSize(LI->getType()), 00270 AliasSet::Refs, NewPtr); 00271 if (LI->isVolatile()) AS.setVolatile(); 00272 return NewPtr; 00273 } 00274 00275 bool AliasSetTracker::add(StoreInst *SI) { 00276 bool NewPtr; 00277 Value *Val = SI->getOperand(0); 00278 AliasSet &AS = addPointer(SI->getOperand(1), 00279 AA.getTargetData().getTypeStoreSize(Val->getType()), 00280 AliasSet::Mods, NewPtr); 00281 if (SI->isVolatile()) AS.setVolatile(); 00282 return NewPtr; 00283 } 00284 00285 bool AliasSetTracker::add(FreeInst *FI) { 00286 bool NewPtr; 00287 addPointer(FI->getOperand(0), ~0, AliasSet::Mods, NewPtr); 00288 return NewPtr; 00289 } 00290 00291 bool AliasSetTracker::add(VAArgInst *VAAI) { 00292 bool NewPtr; 00293 addPointer(VAAI->getOperand(0), ~0, AliasSet::ModRef, NewPtr); 00294 return NewPtr; 00295 } 00296 00297 00298 bool AliasSetTracker::add(CallSite CS) { 00299 if (AA.doesNotAccessMemory(CS)) 00300 return true; // doesn't alias anything 00301 00302 AliasSet *AS = findAliasSetForCallSite(CS); 00303 if (!AS) { 00304 AliasSets.push_back(new AliasSet()); 00305 AS = &AliasSets.back(); 00306 AS->addCallSite(CS, AA); 00307 return true; 00308 } else { 00309 AS->addCallSite(CS, AA); 00310 return false; 00311 } 00312 } 00313 00314 bool AliasSetTracker::add(Instruction *I) { 00315 // Dispatch to one of the other add methods... 00316 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 00317 return add(LI); 00318 else if (StoreInst *SI = dyn_cast<StoreInst>(I)) 00319 return add(SI); 00320 else if (CallInst *CI = dyn_cast<CallInst>(I)) 00321 return add(CI); 00322 else if (InvokeInst *II = dyn_cast<InvokeInst>(I)) 00323 return add(II); 00324 else if (FreeInst *FI = dyn_cast<FreeInst>(I)) 00325 return add(FI); 00326 else if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I)) 00327 return add(VAAI); 00328 return true; 00329 } 00330 00331 void AliasSetTracker::add(BasicBlock &BB) { 00332 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) 00333 add(I); 00334 } 00335 00336 void AliasSetTracker::add(const AliasSetTracker &AST) { 00337 assert(&AA == &AST.AA && 00338 "Merging AliasSetTracker objects with different Alias Analyses!"); 00339 00340 // Loop over all of the alias sets in AST, adding the pointers contained 00341 // therein into the current alias sets. This can cause alias sets to be 00342 // merged together in the current AST. 00343 for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) 00344 if (!I->Forward) { // Ignore forwarding alias sets 00345 AliasSet &AS = const_cast<AliasSet&>(*I); 00346 00347 // If there are any call sites in the alias set, add them to this AST. 00348 for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i) 00349 add(AS.CallSites[i]); 00350 00351 // Loop over all of the pointers in this alias set... 00352 AliasSet::iterator I = AS.begin(), E = AS.end(); 00353 bool X; 00354 for (; I != E; ++I) { 00355 AliasSet &NewAS = addPointer(I.getPointer(), I.getSize(), 00356 (AliasSet::AccessType)AS.AccessTy, X); 00357 if (AS.isVolatile()) NewAS.setVolatile(); 00358 } 00359 } 00360 } 00361 00362 /// remove - Remove the specified (potentially non-empty) alias set from the 00363 /// tracker. 00364 void AliasSetTracker::remove(AliasSet &AS) { 00365 // Drop all call sites. 00366 AS.CallSites.clear(); 00367 00368 // Clear the alias set. 00369 unsigned NumRefs = 0; 00370 while (!AS.empty()) { 00371 AliasSet::HashNodePair *P = AS.PtrList; 00372 00373 // Unlink from the list of values. 00374 P->second.removeFromList(); 00375 00376 // Remember how many references need to be dropped. 00377 ++NumRefs; 00378 00379 // Finally, remove the entry. 00380 Value *Remove = P->first; // Take a copy because it is invalid to pass 00381 PointerMap.erase(Remove); // a reference to the data being erased. 00382 } 00383 00384 // Stop using the alias set, removing it. 00385 AS.RefCount -= NumRefs; 00386 if (AS.RefCount == 0) 00387 AS.removeFromTracker(*this); 00388 } 00389 00390 bool AliasSetTracker::remove(Value *Ptr, unsigned Size) { 00391 AliasSet *AS = findAliasSetForPointer(Ptr, Size); 00392 if (!AS) return false; 00393 remove(*AS); 00394 return true; 00395 } 00396 00397 bool AliasSetTracker::remove(LoadInst *LI) { 00398 unsigned Size = AA.getTargetData().getTypeStoreSize(LI->getType()); 00399 AliasSet *AS = findAliasSetForPointer(LI->getOperand(0), Size); 00400 if (!AS) return false; 00401 remove(*AS); 00402 return true; 00403 } 00404 00405 bool AliasSetTracker::remove(StoreInst *SI) { 00406 unsigned Size = 00407 AA.getTargetData().getTypeStoreSize(SI->getOperand(0)->getType()); 00408 AliasSet *AS = findAliasSetForPointer(SI->getOperand(1), Size); 00409 if (!AS) return false; 00410 remove(*AS); 00411 return true; 00412 } 00413 00414 bool AliasSetTracker::remove(FreeInst *FI) { 00415 AliasSet *AS = findAliasSetForPointer(FI->getOperand(0), ~0); 00416 if (!AS) return false; 00417 remove(*AS); 00418 return true; 00419 } 00420 00421 bool AliasSetTracker::remove(VAArgInst *VAAI) { 00422 AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0), ~0); 00423 if (!AS) return false; 00424 remove(*AS); 00425 return true; 00426 } 00427 00428 bool AliasSetTracker::remove(CallSite CS) { 00429 if (AA.doesNotAccessMemory(CS)) 00430 return false; // doesn't alias anything 00431 00432 AliasSet *AS = findAliasSetForCallSite(CS); 00433 if (!AS) return false; 00434 remove(*AS); 00435 return true; 00436 } 00437 00438 bool AliasSetTracker::remove(Instruction *I) { 00439 // Dispatch to one of the other remove methods... 00440 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 00441 return remove(LI); 00442 else if (StoreInst *SI = dyn_cast<StoreInst>(I)) 00443 return remove(SI); 00444 else if (CallInst *CI = dyn_cast<CallInst>(I)) 00445 return remove(CI); 00446 else if (FreeInst *FI = dyn_cast<FreeInst>(I)) 00447 return remove(FI); 00448 else if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I)) 00449 return remove(VAAI); 00450 return true; 00451 } 00452 00453 00454 // deleteValue method - This method is used to remove a pointer value from the 00455 // AliasSetTracker entirely. It should be used when an instruction is deleted 00456 // from the program to update the AST. If you don't use this, you would have 00457 // dangling pointers to deleted instructions. 00458 // 00459 void AliasSetTracker::deleteValue(Value *PtrVal) { 00460 // Notify the alias analysis implementation that this value is gone. 00461 AA.deleteValue(PtrVal); 00462 00463 // If this is a call instruction, remove the callsite from the appropriate 00464 // AliasSet. 00465 CallSite CS = CallSite::get(PtrVal); 00466 if (CS.getInstruction()) 00467 if (!AA.doesNotAccessMemory(CS)) 00468 if (AliasSet *AS = findAliasSetForCallSite(CS)) 00469 AS->removeCallSite(CS); 00470 00471 // First, look up the PointerRec for this pointer. 00472 hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(PtrVal); 00473 if (I == PointerMap.end()) return; // Noop 00474 00475 // If we found one, remove the pointer from the alias set it is in. 00476 AliasSet::HashNodePair &PtrValEnt = *I; 00477 AliasSet *AS = PtrValEnt.second.getAliasSet(*this); 00478 00479 // Unlink from the list of values... 00480 PtrValEnt.second.removeFromList(); 00481 // Stop using the alias set 00482 AS->dropRef(*this); 00483 PointerMap.erase(I); 00484 } 00485 00486 // copyValue - This method should be used whenever a preexisting value in the 00487 // program is copied or cloned, introducing a new value. Note that it is ok for 00488 // clients that use this method to introduce the same value multiple times: if 00489 // the tracker already knows about a value, it will ignore the request. 00490 // 00491 void AliasSetTracker::copyValue(Value *From, Value *To) { 00492 // Notify the alias analysis implementation that this value is copied. 00493 AA.copyValue(From, To); 00494 00495 // First, look up the PointerRec for this pointer. 00496 hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(From); 00497 if (I == PointerMap.end() || !I->second.hasAliasSet()) 00498 return; // Noop 00499 00500 AliasSet::HashNodePair &Entry = getEntryFor(To); 00501 if (Entry.second.hasAliasSet()) return; // Already in the tracker! 00502 00503 // Add it to the alias set it aliases... 00504 AliasSet *AS = I->second.getAliasSet(*this); 00505 AS->addPointer(*this, Entry, I->second.getSize(), true); 00506 } 00507 00508 00509 00510 //===----------------------------------------------------------------------===// 00511 // AliasSet/AliasSetTracker Printing Support 00512 //===----------------------------------------------------------------------===// 00513 00514 void AliasSet::print(std::ostream &OS) const { 00515 OS << " AliasSet[" << (void*)this << "," << RefCount << "] "; 00516 OS << (AliasTy == MustAlias ? "must" : "may") << " alias, "; 00517 switch (AccessTy) { 00518 case NoModRef: OS << "No access "; break; 00519 case Refs : OS << "Ref "; break; 00520 case Mods : OS << "Mod "; break; 00521 case ModRef : OS << "Mod/Ref "; break; 00522 default: assert(0 && "Bad value for AccessTy!"); 00523 } 00524 if (isVolatile()) OS << "[volatile] "; 00525 if (Forward) 00526 OS << " forwarding to " << (void*)Forward; 00527 00528 00529 if (!empty()) { 00530 OS << "Pointers: "; 00531 for (iterator I = begin(), E = end(); I != E; ++I) { 00532 if (I != begin()) OS << ", "; 00533 WriteAsOperand(OS << "(", I.getPointer()); 00534 OS << ", " << I.getSize() << ")"; 00535 } 00536 } 00537 if (!CallSites.empty()) { 00538 OS << "\n " << CallSites.size() << " Call Sites: "; 00539 for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { 00540 if (i) OS << ", "; 00541 WriteAsOperand(OS, CallSites[i].getCalledValue()); 00542 } 00543 } 00544 OS << "\n"; 00545 } 00546 00547 void AliasSetTracker::print(std::ostream &OS) const { 00548 OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for " 00549 << PointerMap.size() << " pointer values.\n"; 00550 for (const_iterator I = begin(), E = end(); I != E; ++I) 00551 I->print(OS); 00552 OS << "\n"; 00553 } 00554 00555 void AliasSet::dump() const { print (cerr); } 00556 void AliasSetTracker::dump() const { print(cerr); } 00557 00558 //===----------------------------------------------------------------------===// 00559 // AliasSetPrinter Pass 00560 //===----------------------------------------------------------------------===// 00561 00562 namespace { 00563 class VISIBILITY_HIDDEN AliasSetPrinter : public FunctionPass { 00564 AliasSetTracker *Tracker; 00565 public: 00566 static char ID; // Pass identification, replacement for typeid 00567 AliasSetPrinter() : FunctionPass(&ID) {} 00568 00569 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00570 AU.setPreservesAll(); 00571 AU.addRequired<AliasAnalysis>(); 00572 } 00573 00574 virtual bool runOnFunction(Function &F) { 00575 Tracker = new AliasSetTracker(getAnalysis<AliasAnalysis>()); 00576 00577 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) 00578 Tracker->add(&*I); 00579 Tracker->print(cerr); 00580 delete Tracker; 00581 return false; 00582 } 00583 }; 00584 } 00585 00586 char AliasSetPrinter::ID = 0; 00587 static RegisterPass<AliasSetPrinter> 00588 X("print-alias-sets", "Alias Set Printer", false, true);