1 //===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===// 2 // 3 // This file implements the AliasSetTracker and AliasSet classes. 4 // 5 //===----------------------------------------------------------------------===// 6 7 #include "llvm/Analysis/AliasSetTracker.h" 8 #include "llvm/Analysis/AliasAnalysis.h" 9 #include "llvm/iMemory.h" 10 #include "llvm/iOther.h" 11 #include "llvm/iTerminators.h" 12 #include "llvm/Pass.h" 13 #include "llvm/Target/TargetData.h" 14 #include "llvm/Assembly/Writer.h" 15 #include "llvm/Support/InstIterator.h" 16 17 /// mergeSetIn - Merge the specified alias set into this alias set... 18 /// 19 void AliasSet::mergeSetIn(AliasSet &AS) { 20 assert(!AS.Forward && "Alias set is already forwarding!"); 21 assert(!Forward && "This set is a forwarding set!!"); 22 23 // Update the alias and access types of this set... 24 AccessTy |= AS.AccessTy; 25 AliasTy |= AS.AliasTy; 26 27 if (CallSites.empty()) { // Merge call sites... 28 if (!AS.CallSites.empty()) 29 std::swap(CallSites, AS.CallSites); 30 } else if (!AS.CallSites.empty()) { 31 CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end()); 32 AS.CallSites.clear(); 33 } 34 35 // FIXME: If AS's refcount is zero, nuke it now... 36 assert(RefCount != 0); 37 38 AS.Forward = this; // Forward across AS now... 39 RefCount++; // AS is now pointing to us... 40 41 // Merge the list of constituent pointers... 42 PtrListTail->second.setTail(AS.PtrListHead); 43 PtrListTail = AS.PtrListTail; 44 AS.PtrListHead = AS.PtrListTail = 0; 45 } 46 47 void AliasSetTracker::removeAliasSet(AliasSet *AS) { 48 AliasSets.erase(AS); 49 } 50 51 void AliasSet::removeFromTracker(AliasSetTracker &AST) { 52 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!"); 53 AST.removeAliasSet(this); 54 } 55 56 void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry, 57 unsigned Size) { 58 assert(!Entry.second.hasAliasSet() && "Entry already in set!"); 59 60 AliasAnalysis &AA = AST.getAliasAnalysis(); 61 62 if (isMustAlias()) // Check to see if we have to downgrade to _may_ alias 63 if (HashNodePair *P = getSomePointer()) { 64 AliasAnalysis::AliasResult Result = 65 AA.alias(P->first, P->second.getSize(), Entry.first, Size); 66 if (Result == AliasAnalysis::MayAlias) 67 AliasTy = MayAlias; 68 else // First entry of must alias must have maximum size! 69 P->second.updateSize(Size); 70 assert(Result != AliasAnalysis::NoAlias && "Cannot be part of must set!"); 71 } 72 73 Entry.second.setAliasSet(this); 74 Entry.second.updateSize(Size); 75 76 // Add it to the end of the list... 77 if (PtrListTail) 78 PtrListTail->second.setTail(&Entry); 79 else 80 PtrListHead = &Entry; 81 PtrListTail = &Entry; 82 RefCount++; // Entry points to alias set... 83 } 84 85 void AliasSet::addCallSite(CallSite CS) { 86 CallSites.push_back(CS); 87 AliasTy = MayAlias; // FIXME: Too conservative? 88 AccessTy = ModRef; 89 } 90 91 /// aliasesPointer - Return true if the specified pointer "may" (or must) 92 /// alias one of the members in the set. 93 /// 94 bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size, 95 AliasAnalysis &AA) const { 96 if (AliasTy == MustAlias) { 97 assert(CallSites.empty() && "Illegal must alias set!"); 98 99 // If this is a set of MustAliases, only check to see if the pointer aliases 100 // SOME value in the set... 101 HashNodePair *SomePtr = getSomePointer(); 102 assert(SomePtr && "Empty must-alias set??"); 103 return AA.alias(SomePtr->first, SomePtr->second.getSize(), Ptr, Size); 104 } 105 106 // If this is a may-alias set, we have to check all of the pointers in the set 107 // to be sure it doesn't alias the set... 108 for (iterator I = begin(), E = end(); I != E; ++I) 109 if (AA.alias(Ptr, Size, I->first, I->second.getSize())) 110 return true; 111 112 // Check the call sites list and invoke list... 113 if (!CallSites.empty()) 114 // FIXME: this is pessimistic! 115 return true; 116 117 return false; 118 } 119 120 bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { 121 // FIXME: Too conservative! 122 return true; 123 } 124 125 126 /// findAliasSetForPointer - Given a pointer, find the one alias set to put the 127 /// instruction referring to the pointer into. If there are multiple alias sets 128 /// that may alias the pointer, merge them together and return the unified set. 129 /// 130 AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr, 131 unsigned Size) { 132 AliasSet *FoundSet = 0; 133 for (iterator I = begin(), E = end(); I != E; ++I) 134 if (!I->Forward && I->aliasesPointer(Ptr, Size, AA)) { 135 if (FoundSet == 0) { // If this is the first alias set ptr can go into... 136 FoundSet = I; // Remember it. 137 } else { // Otherwise, we must merge the sets... 138 FoundSet->mergeSetIn(*I); // Merge in contents... 139 } 140 } 141 142 return FoundSet; 143 } 144 145 AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) { 146 AliasSet *FoundSet = 0; 147 for (iterator I = begin(), E = end(); I != E; ++I) 148 if (!I->Forward && I->aliasesCallSite(CS, AA)) { 149 if (FoundSet == 0) { // If this is the first alias set ptr can go into... 150 FoundSet = I; // Remember it. 151 } else if (!I->Forward) { // Otherwise, we must merge the sets... 152 FoundSet->mergeSetIn(*I); // Merge in contents... 153 } 154 } 155 156 return FoundSet; 157 } 158 159 160 161 162 /// getAliasSetForPointer - Return the alias set that the specified pointer 163 /// lives in... 164 AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, unsigned Size){ 165 AliasSet::HashNodePair &Entry = getEntryFor(Pointer); 166 167 // Check to see if the pointer is already known... 168 if (Entry.second.hasAliasSet() && Size <= Entry.second.getSize()) { 169 // Return the set! 170 return *Entry.second.getAliasSet(*this)->getForwardedTarget(*this); 171 } else if (AliasSet *AS = findAliasSetForPointer(Pointer, Size)) { 172 // Add it to the alias set it aliases... 173 AS->addPointer(*this, Entry, Size); 174 return *AS; 175 } else { 176 // Otherwise create a new alias set to hold the loaded pointer... 177 AliasSets.push_back(AliasSet()); 178 AliasSets.back().addPointer(*this, Entry, Size); 179 return AliasSets.back(); 180 } 181 } 182 183 void AliasSetTracker::add(LoadInst *LI) { 184 addPointer(LI->getOperand(0), 185 AA.getTargetData().getTypeSize(LI->getType()), AliasSet::Refs); 186 } 187 188 void AliasSetTracker::add(StoreInst *SI) { 189 addPointer(SI->getOperand(1), 190 AA.getTargetData().getTypeSize(SI->getOperand(0)->getType()), 191 AliasSet::Mods); 192 } 193 194 void AliasSetTracker::add(CallSite CS) { 195 AliasSet *AS = findAliasSetForCallSite(CS); 196 if (!AS) { 197 AliasSets.push_back(AliasSet()); 198 AS = &AliasSets.back(); 199 } 200 AS->addCallSite(CS); 201 } 202 203 void AliasSetTracker::add(Instruction *I) { 204 // Dispatch to one of the other add methods... 205 if (LoadInst *LI = dyn_cast<LoadInst>(I)) 206 add(LI); 207 else if (StoreInst *SI = dyn_cast<StoreInst>(I)) 208 add(SI); 209 else if (CallInst *CI = dyn_cast<CallInst>(I)) 210 add(CI); 211 else if (InvokeInst *II = dyn_cast<InvokeInst>(I)) 212 add(II); 213 } 214 215 void AliasSetTracker::add(BasicBlock &BB) { 216 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) 217 add(I); 218 } 219 220 void AliasSetTracker::add(const AliasSetTracker &AST) { 221 assert(&AA == &AST.AA && 222 "Merging AliasSetTracker objects with different Alias Analyses!"); 223 224 // Loop over all of the alias sets in AST, adding the pointers contained 225 // therein into the current alias sets. This can cause alias sets to be 226 // merged together in the current AST. 227 for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) 228 if (!I->Forward) { // Ignore forwarding alias sets 229 AliasSet &AS = const_cast<AliasSet&>(*I); 230 231 // If there are any call sites in the alias set, add them to this AST. 232 for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i) 233 add(AS.CallSites[i]); 234 235 // Loop over all of the pointers in this alias set... 236 AliasSet::iterator I = AS.begin(), E = AS.end(); 237 for (; I != E; ++I) 238 addPointer(I->first, I->second.getSize(), 239 (AliasSet::AccessType)AS.AccessTy); 240 } 241 } 242 243 //===----------------------------------------------------------------------===// 244 // AliasSet/AliasSetTracker Printing Support 245 //===----------------------------------------------------------------------===// 246 247 void AliasSet::print(std::ostream &OS) const { 248 OS << " AliasSet[" << (void*)this << "," << RefCount << "] "; 249 OS << (AliasTy == MustAlias ? "must" : "may ") << " alias, "; 250 switch (AccessTy) { 251 case NoModRef: OS << "No access "; break; 252 case Refs : OS << "Ref "; break; 253 case Mods : OS << "Mod "; break; 254 case ModRef : OS << "Mod/Ref "; break; 255 default: assert(0 && "Bad value for AccessTy!"); 256 } 257 if (Forward) 258 OS << " forwarding to " << (void*)Forward; 259 260 261 if (begin() != end()) { 262 OS << "Pointers: "; 263 for (iterator I = begin(), E = end(); I != E; ++I) { 264 if (I != begin()) OS << ", "; 265 WriteAsOperand(OS << "(", I->first); 266 OS << ", " << I->second.getSize() << ")"; 267 } 268 } 269 if (!CallSites.empty()) { 270 OS << "\n " << CallSites.size() << " Call Sites: "; 271 for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { 272 if (i) OS << ", "; 273 WriteAsOperand(OS, CallSites[i].getCalledValue()); 274 } 275 } 276 OS << "\n"; 277 } 278 279 void AliasSetTracker::print(std::ostream &OS) const { 280 OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for " 281 << PointerMap.size() << " pointer values.\n"; 282 for (const_iterator I = begin(), E = end(); I != E; ++I) 283 I->print(OS); 284 OS << "\n"; 285 } 286 287 void AliasSet::dump() const { print (std::cerr); } 288 void AliasSetTracker::dump() const { print(std::cerr); } 289 290 291 //===----------------------------------------------------------------------===// 292 // AliasSetPrinter Pass 293 //===----------------------------------------------------------------------===// 294 295 namespace { 296 class AliasSetPrinter : public FunctionPass { 297 AliasSetTracker *Tracker; 298 public: 299 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 300 AU.setPreservesAll(); 301 AU.addRequired<AliasAnalysis>(); 302 } 303 304 virtual bool runOnFunction(Function &F) { 305 Tracker = new AliasSetTracker(getAnalysis<AliasAnalysis>()); 306 307 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) 308 Tracker->add(*I); 309 return false; 310 } 311 312 /// print - Convert to human readable form 313 virtual void print(std::ostream &OS) const { 314 Tracker->print(OS); 315 } 316 317 virtual void releaseMemory() { 318 delete Tracker; 319 } 320 }; 321 RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer", 322 PassInfo::Analysis | PassInfo::Optimization); 323 } 324