- Timestamp:
- Apr 19, 2011, 11:12:07 PM (14 years ago)
- Location:
- clamav/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
clamav/trunk ¶
-
Property svn:mergeinfo
set to
/clamav/vendor/0.97 merged eligible
-
Property svn:mergeinfo
set to
-
TabularUnified clamav/trunk/libclamav/c++/llvm/lib/Analysis/IPA/GlobalsModRef.cpp ¶
r189 r319 48 48 /// addresses taken that are read or written (transitively) by this 49 49 /// function. 50 std::map< GlobalValue*, unsigned> GlobalInfo;50 std::map<const GlobalValue*, unsigned> GlobalInfo; 51 51 52 52 /// MayReadAnyGlobal - May read global variables, but it is not known which. 53 53 bool MayReadAnyGlobal; 54 54 55 unsigned getInfoForGlobal( GlobalValue *GV) const {55 unsigned getInfoForGlobal(const GlobalValue *GV) const { 56 56 unsigned Effect = MayReadAnyGlobal ? AliasAnalysis::Ref : 0; 57 std::map<GlobalValue*, unsigned>::const_iterator I = GlobalInfo.find(GV); 57 std::map<const GlobalValue*, unsigned>::const_iterator I = 58 GlobalInfo.find(GV); 58 59 if (I != GlobalInfo.end()) 59 60 Effect |= I->second; … … 72 73 /// NonAddressTakenGlobals - The globals that do not have their addresses 73 74 /// taken. 74 std::set< GlobalValue*> NonAddressTakenGlobals;75 std::set<const GlobalValue*> NonAddressTakenGlobals; 75 76 76 77 /// IndirectGlobals - The memory pointed to by this global is known to be 77 78 /// 'owned' by the global. 78 std::set< GlobalValue*> IndirectGlobals;79 std::set<const GlobalValue*> IndirectGlobals; 79 80 80 81 /// AllocsForIndirectGlobals - If an instruction allocates memory for an 81 82 /// indirect global, this map indicates which one. 82 std::map< Value*,GlobalValue*> AllocsForIndirectGlobals;83 std::map<const Value*, const GlobalValue*> AllocsForIndirectGlobals; 83 84 84 85 /// FunctionInfo - For each function, keep track of what globals are 85 86 /// modified or read. 86 std::map< Function*, FunctionRecord> FunctionInfo;87 std::map<const Function*, FunctionRecord> FunctionInfo; 87 88 88 89 public: 89 90 static char ID; 90 GlobalsModRef() : ModulePass( &ID) {}91 GlobalsModRef() : ModulePass(ID) {} 91 92 92 93 bool runOnModule(Module &M) { … … 108 109 AliasResult alias(const Value *V1, unsigned V1Size, 109 110 const Value *V2, unsigned V2Size); 110 ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); 111 ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) { 112 return AliasAnalysis::getModRefInfo(CS1,CS2); 111 ModRefResult getModRefInfo(ImmutableCallSite CS, 112 const Value *P, unsigned Size); 113 ModRefResult getModRefInfo(ImmutableCallSite CS1, 114 ImmutableCallSite CS2) { 115 return AliasAnalysis::getModRefInfo(CS1, CS2); 113 116 } 114 117 … … 116 119 /// called from the specified call site. The call site may be null in which 117 120 /// case the most generic behavior of this function should be returned. 118 ModRefBehavior getModRefBehavior(Function *F, 119 std::vector<PointerAccessInfo> *Info) { 121 ModRefBehavior getModRefBehavior(const Function *F) { 120 122 if (FunctionRecord *FR = getFunctionInfo(F)) { 121 123 if (FR->FunctionEffect == 0) … … 124 126 return OnlyReadsMemory; 125 127 } 126 return AliasAnalysis::getModRefBehavior(F , Info);128 return AliasAnalysis::getModRefBehavior(F); 127 129 } 128 130 … … 130 132 /// called from the specified call site. The call site may be null in which 131 133 /// case the most generic behavior of this function should be returned. 132 ModRefBehavior getModRefBehavior(CallSite CS, 133 std::vector<PointerAccessInfo> *Info) { 134 Function* F = CS.getCalledFunction(); 135 if (!F) return AliasAnalysis::getModRefBehavior(CS, Info); 134 ModRefBehavior getModRefBehavior(ImmutableCallSite CS) { 135 const Function* F = CS.getCalledFunction(); 136 if (!F) return AliasAnalysis::getModRefBehavior(CS); 136 137 if (FunctionRecord *FR = getFunctionInfo(F)) { 137 138 if (FR->FunctionEffect == 0) … … 140 141 return OnlyReadsMemory; 141 142 } 142 return AliasAnalysis::getModRefBehavior(CS , Info);143 return AliasAnalysis::getModRefBehavior(CS); 143 144 } 144 145 … … 150 151 /// should override this to adjust the this pointer as needed for the 151 152 /// specified pass info. 152 virtual void *getAdjustedAnalysisPointer( const PassInfo *PI) {153 if (PI ->isPassID(&AliasAnalysis::ID))153 virtual void *getAdjustedAnalysisPointer(AnalysisID PI) { 154 if (PI == &AliasAnalysis::ID) 154 155 return (AliasAnalysis*)this; 155 156 return this; … … 159 160 /// getFunctionInfo - Return the function info for the function, or null if 160 161 /// we don't have anything useful to say about it. 161 FunctionRecord *getFunctionInfo(Function *F) { 162 std::map<Function*, FunctionRecord>::iterator I = FunctionInfo.find(F); 162 FunctionRecord *getFunctionInfo(const Function *F) { 163 std::map<const Function*, FunctionRecord>::iterator I = 164 FunctionInfo.find(F); 163 165 if (I != FunctionInfo.end()) 164 166 return &I->second; … … 176 178 177 179 char GlobalsModRef::ID = 0; 178 static RegisterPass<GlobalsModRef> 179 X("globalsmodref-aa", "Simple mod/ref analysis for globals", false, true); 180 static RegisterAnalysisGroup<AliasAnalysis> Y(X);180 INITIALIZE_AG_PASS(GlobalsModRef, AliasAnalysis, 181 "globalsmodref-aa", "Simple mod/ref analysis for globals", 182 false, true, false); 181 183 182 184 Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); } … … 234 236 if (!V->getType()->isPointerTy()) return true; 235 237 236 for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI) 237 if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) { 238 for (Value::use_iterator UI = V->use_begin(), E=V->use_end(); UI != E; ++UI) { 239 User *U = *UI; 240 if (LoadInst *LI = dyn_cast<LoadInst>(U)) { 238 241 Readers.push_back(LI->getParent()->getParent()); 239 } else if (StoreInst *SI = dyn_cast<StoreInst>( *UI)) {242 } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) { 240 243 if (V == SI->getOperand(1)) { 241 244 Writers.push_back(SI->getParent()->getParent()); … … 243 246 return true; // Storing the pointer 244 247 } 245 } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>( *UI)) {248 } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) { 246 249 if (AnalyzeUsesOfPointer(GEP, Readers, Writers)) return true; 247 } else if (BitCastInst *BCI = dyn_cast<BitCastInst>( *UI)) {250 } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(U)) { 248 251 if (AnalyzeUsesOfPointer(BCI, Readers, Writers, OkayStoreDest)) 249 252 return true; 250 } else if (isFreeCall( *UI)) {251 Writers.push_back(cast<Instruction>( *UI)->getParent()->getParent());252 } else if (CallInst *CI = dyn_cast<CallInst>( *UI)) {253 } else if (isFreeCall(U)) { 254 Writers.push_back(cast<Instruction>(U)->getParent()->getParent()); 255 } else if (CallInst *CI = dyn_cast<CallInst>(U)) { 253 256 // Make sure that this is just the function being called, not that it is 254 257 // passing into the function. 255 for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)256 if (CI->get Operand(i) == V) return true;257 } else if (InvokeInst *II = dyn_cast<InvokeInst>( *UI)) {258 for (unsigned i = 0, e = CI->getNumArgOperands(); i != e; ++i) 259 if (CI->getArgOperand(i) == V) return true; 260 } else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) { 258 261 // Make sure that this is just the function being called, not that it is 259 262 // passing into the function. 260 for (unsigned i = 3, e = II->getNumOperands(); i != e; ++i)261 if (II->get Operand(i) == V) return true;262 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>( *UI)) {263 for (unsigned i = 0, e = II->getNumArgOperands(); i != e; ++i) 264 if (II->getArgOperand(i) == V) return true; 265 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) { 263 266 if (CE->getOpcode() == Instruction::GetElementPtr || 264 267 CE->getOpcode() == Instruction::BitCast) { … … 268 271 return true; 269 272 } 270 } else if (ICmpInst *ICI = dyn_cast<ICmpInst>( *UI)) {273 } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(U)) { 271 274 if (!isa<ConstantPointerNull>(ICI->getOperand(1))) 272 275 return true; // Allow comparison against null. … … 274 277 return true; 275 278 } 279 } 280 276 281 return false; 277 282 } … … 292 297 // load or store, bail out. 293 298 for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I){ 294 if (LoadInst *LI = dyn_cast<LoadInst>(*I)) { 299 User *U = *I; 300 if (LoadInst *LI = dyn_cast<LoadInst>(U)) { 295 301 // The pointer loaded from the global can only be used in simple ways: 296 302 // we allow addressing of it and loading storing to it. We do *not* allow … … 300 306 return false; // Loaded pointer escapes. 301 307 // TODO: Could try some IP mod/ref of the loaded pointer. 302 } else if (StoreInst *SI = dyn_cast<StoreInst>( *I)) {308 } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) { 303 309 // Storing the global itself. 304 310 if (SI->getOperand(0) == GV) return false; … … 406 412 407 413 // Incorporate callee's effects on globals into our info. 408 for (std::map< GlobalValue*, unsigned>::iterator GI =414 for (std::map<const GlobalValue*, unsigned>::iterator GI = 409 415 CalleeFR->GlobalInfo.begin(), E = CalleeFR->GlobalInfo.end(); 410 416 GI != E; ++GI) … … 474 480 const Value *V2, unsigned V2Size) { 475 481 // Get the base object these pointers point to. 476 Value *UV1 = const_cast<Value*>(V1->getUnderlyingObject());477 Value *UV2 = const_cast<Value*>(V2->getUnderlyingObject());482 const Value *UV1 = V1->getUnderlyingObject(); 483 const Value *UV2 = V2->getUnderlyingObject(); 478 484 479 485 // If either of the underlying values is a global, they may be non-addr-taken 480 486 // globals, which we can answer queries about. 481 GlobalValue *GV1 = dyn_cast<GlobalValue>(UV1);482 GlobalValue *GV2 = dyn_cast<GlobalValue>(UV2);487 const GlobalValue *GV1 = dyn_cast<GlobalValue>(UV1); 488 const GlobalValue *GV2 = dyn_cast<GlobalValue>(UV2); 483 489 if (GV1 || GV2) { 484 490 // If the global's address is taken, pretend we don't know it's a pointer to … … 500 506 // is a direct load from an indirect global. 501 507 GV1 = GV2 = 0; 502 if ( LoadInst *LI = dyn_cast<LoadInst>(UV1))508 if (const LoadInst *LI = dyn_cast<LoadInst>(UV1)) 503 509 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0))) 504 510 if (IndirectGlobals.count(GV)) 505 511 GV1 = GV; 506 if ( LoadInst *LI = dyn_cast<LoadInst>(UV2))507 if ( GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))512 if (const LoadInst *LI = dyn_cast<LoadInst>(UV2)) 513 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0))) 508 514 if (IndirectGlobals.count(GV)) 509 515 GV2 = GV; … … 527 533 528 534 AliasAnalysis::ModRefResult 529 GlobalsModRef::getModRefInfo(CallSite CS, Value *P, unsigned Size) { 535 GlobalsModRef::getModRefInfo(ImmutableCallSite CS, 536 const Value *P, unsigned Size) { 530 537 unsigned Known = ModRef; 531 538 532 539 // If we are asking for mod/ref info of a direct call with a pointer to a 533 540 // global we are tracking, return information if we have it. 534 if ( GlobalValue *GV = dyn_cast<GlobalValue>(P->getUnderlyingObject()))541 if (const GlobalValue *GV = dyn_cast<GlobalValue>(P->getUnderlyingObject())) 535 542 if (GV->hasLocalLinkage()) 536 if ( Function *F = CS.getCalledFunction())543 if (const Function *F = CS.getCalledFunction()) 537 544 if (NonAddressTakenGlobals.count(GV)) 538 if ( FunctionRecord *FR = getFunctionInfo(F))545 if (const FunctionRecord *FR = getFunctionInfo(F)) 539 546 Known = FR->getInfoForGlobal(GV); 540 547 … … 555 562 if (IndirectGlobals.erase(GV)) { 556 563 // Remove any entries in AllocsForIndirectGlobals for this global. 557 for (std::map< Value*,GlobalValue*>::iterator564 for (std::map<const Value*, const GlobalValue*>::iterator 558 565 I = AllocsForIndirectGlobals.begin(), 559 566 E = AllocsForIndirectGlobals.end(); I != E; ) {
Note:
See TracChangeset
for help on using the changeset viewer.