~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Analysis/IPA/GlobalsModRef.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//===- GlobalsModRef.cpp - Simple Mod/Ref Analysis for Globals ------------===//
2
 
//
3
 
//                     The LLVM Compiler Infrastructure
4
 
//
5
 
// This file is distributed under the University of Illinois Open Source
6
 
// License. See LICENSE.TXT for details.
7
 
//
8
 
//===----------------------------------------------------------------------===//
9
 
//
10
 
// This simple pass provides alias and mod/ref information for global values
11
 
// that do not have their address taken, and keeps track of whether functions
12
 
// read or write memory (are "pure").  For this simple (but very common) case,
13
 
// we can provide pretty accurate and useful information.
14
 
//
15
 
//===----------------------------------------------------------------------===//
16
 
 
17
 
#define DEBUG_TYPE "globalsmodref-aa"
18
 
#include "llvm/Analysis/Passes.h"
19
 
#include "llvm/Module.h"
20
 
#include "llvm/Pass.h"
21
 
#include "llvm/Instructions.h"
22
 
#include "llvm/Constants.h"
23
 
#include "llvm/DerivedTypes.h"
24
 
#include "llvm/Analysis/AliasAnalysis.h"
25
 
#include "llvm/Analysis/CallGraph.h"
26
 
#include "llvm/Analysis/MemoryBuiltins.h"
27
 
#include "llvm/Support/CommandLine.h"
28
 
#include "llvm/Support/InstIterator.h"
29
 
#include "llvm/ADT/Statistic.h"
30
 
#include "llvm/ADT/SCCIterator.h"
31
 
#include <set>
32
 
using namespace llvm;
33
 
 
34
 
STATISTIC(NumNonAddrTakenGlobalVars,
35
 
          "Number of global vars without address taken");
36
 
STATISTIC(NumNonAddrTakenFunctions,"Number of functions without address taken");
37
 
STATISTIC(NumNoMemFunctions, "Number of functions that do not access memory");
38
 
STATISTIC(NumReadMemFunctions, "Number of functions that only read memory");
39
 
STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");
40
 
 
41
 
namespace {
42
 
  /// FunctionRecord - One instance of this structure is stored for every
43
 
  /// function in the program.  Later, the entries for these functions are
44
 
  /// removed if the function is found to call an external function (in which
45
 
  /// case we know nothing about it.
46
 
  struct FunctionRecord {
47
 
    /// GlobalInfo - Maintain mod/ref info for all of the globals without
48
 
    /// addresses taken that are read or written (transitively) by this
49
 
    /// function.
50
 
    std::map<const GlobalValue*, unsigned> GlobalInfo;
51
 
 
52
 
    /// MayReadAnyGlobal - May read global variables, but it is not known which.
53
 
    bool MayReadAnyGlobal;
54
 
 
55
 
    unsigned getInfoForGlobal(const GlobalValue *GV) const {
56
 
      unsigned Effect = MayReadAnyGlobal ? AliasAnalysis::Ref : 0;
57
 
      std::map<const GlobalValue*, unsigned>::const_iterator I =
58
 
        GlobalInfo.find(GV);
59
 
      if (I != GlobalInfo.end())
60
 
        Effect |= I->second;
61
 
      return Effect;
62
 
    }
63
 
 
64
 
    /// FunctionEffect - Capture whether or not this function reads or writes to
65
 
    /// ANY memory.  If not, we can do a lot of aggressive analysis on it.
66
 
    unsigned FunctionEffect;
67
 
 
68
 
    FunctionRecord() : MayReadAnyGlobal (false), FunctionEffect(0) {}
69
 
  };
70
 
 
71
 
  /// GlobalsModRef - The actual analysis pass.
72
 
  class GlobalsModRef : public ModulePass, public AliasAnalysis {
73
 
    /// NonAddressTakenGlobals - The globals that do not have their addresses
74
 
    /// taken.
75
 
    std::set<const GlobalValue*> NonAddressTakenGlobals;
76
 
 
77
 
    /// IndirectGlobals - The memory pointed to by this global is known to be
78
 
    /// 'owned' by the global.
79
 
    std::set<const GlobalValue*> IndirectGlobals;
80
 
 
81
 
    /// AllocsForIndirectGlobals - If an instruction allocates memory for an
82
 
    /// indirect global, this map indicates which one.
83
 
    std::map<const Value*, const GlobalValue*> AllocsForIndirectGlobals;
84
 
 
85
 
    /// FunctionInfo - For each function, keep track of what globals are
86
 
    /// modified or read.
87
 
    std::map<const Function*, FunctionRecord> FunctionInfo;
88
 
 
89
 
  public:
90
 
    static char ID;
91
 
    GlobalsModRef() : ModulePass(ID) {}
92
 
 
93
 
    bool runOnModule(Module &M) {
94
 
      InitializeAliasAnalysis(this);                 // set up super class
95
 
      AnalyzeGlobals(M);                          // find non-addr taken globals
96
 
      AnalyzeCallGraph(getAnalysis<CallGraph>(), M); // Propagate on CG
97
 
      return false;
98
 
    }
99
 
 
100
 
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
101
 
      AliasAnalysis::getAnalysisUsage(AU);
102
 
      AU.addRequired<CallGraph>();
103
 
      AU.setPreservesAll();                         // Does not transform code
104
 
    }
105
 
 
106
 
    //------------------------------------------------
107
 
    // Implement the AliasAnalysis API
108
 
    //
109
 
    AliasResult alias(const Value *V1, unsigned V1Size,
110
 
                      const Value *V2, unsigned V2Size);
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);
116
 
    }
117
 
 
118
 
    /// getModRefBehavior - Return the behavior of the specified function if
119
 
    /// called from the specified call site.  The call site may be null in which
120
 
    /// case the most generic behavior of this function should be returned.
121
 
    ModRefBehavior getModRefBehavior(const Function *F) {
122
 
      if (FunctionRecord *FR = getFunctionInfo(F)) {
123
 
        if (FR->FunctionEffect == 0)
124
 
          return DoesNotAccessMemory;
125
 
        else if ((FR->FunctionEffect & Mod) == 0)
126
 
          return OnlyReadsMemory;
127
 
      }
128
 
      return AliasAnalysis::getModRefBehavior(F);
129
 
    }
130
 
    
131
 
    /// getModRefBehavior - Return the behavior of the specified function if
132
 
    /// called from the specified call site.  The call site may be null in which
133
 
    /// case the most generic behavior of this function should be returned.
134
 
    ModRefBehavior getModRefBehavior(ImmutableCallSite CS) {
135
 
      const Function* F = CS.getCalledFunction();
136
 
      if (!F) return AliasAnalysis::getModRefBehavior(CS);
137
 
      if (FunctionRecord *FR = getFunctionInfo(F)) {
138
 
        if (FR->FunctionEffect == 0)
139
 
          return DoesNotAccessMemory;
140
 
        else if ((FR->FunctionEffect & Mod) == 0)
141
 
          return OnlyReadsMemory;
142
 
      }
143
 
      return AliasAnalysis::getModRefBehavior(CS);
144
 
    }
145
 
 
146
 
    virtual void deleteValue(Value *V);
147
 
    virtual void copyValue(Value *From, Value *To);
148
 
 
149
 
    /// getAdjustedAnalysisPointer - This method is used when a pass implements
150
 
    /// an analysis interface through multiple inheritance.  If needed, it
151
 
    /// should override this to adjust the this pointer as needed for the
152
 
    /// specified pass info.
153
 
    virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
154
 
      if (PI == &AliasAnalysis::ID)
155
 
        return (AliasAnalysis*)this;
156
 
      return this;
157
 
    }
158
 
    
159
 
  private:
160
 
    /// getFunctionInfo - Return the function info for the function, or null if
161
 
    /// we don't have anything useful to say about it.
162
 
    FunctionRecord *getFunctionInfo(const Function *F) {
163
 
      std::map<const Function*, FunctionRecord>::iterator I =
164
 
        FunctionInfo.find(F);
165
 
      if (I != FunctionInfo.end())
166
 
        return &I->second;
167
 
      return 0;
168
 
    }
169
 
 
170
 
    void AnalyzeGlobals(Module &M);
171
 
    void AnalyzeCallGraph(CallGraph &CG, Module &M);
172
 
    bool AnalyzeUsesOfPointer(Value *V, std::vector<Function*> &Readers,
173
 
                              std::vector<Function*> &Writers,
174
 
                              GlobalValue *OkayStoreDest = 0);
175
 
    bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
176
 
  };
177
 
}
178
 
 
179
 
char GlobalsModRef::ID = 0;
180
 
INITIALIZE_AG_PASS(GlobalsModRef, AliasAnalysis,
181
 
                "globalsmodref-aa", "Simple mod/ref analysis for globals",    
182
 
                false, true, false);
183
 
 
184
 
Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
185
 
 
186
 
/// AnalyzeGlobals - Scan through the users of all of the internal
187
 
/// GlobalValue's in the program.  If none of them have their "address taken"
188
 
/// (really, their address passed to something nontrivial), record this fact,
189
 
/// and record the functions that they are used directly in.
190
 
void GlobalsModRef::AnalyzeGlobals(Module &M) {
191
 
  std::vector<Function*> Readers, Writers;
192
 
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
193
 
    if (I->hasLocalLinkage()) {
194
 
      if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
195
 
        // Remember that we are tracking this global.
196
 
        NonAddressTakenGlobals.insert(I);
197
 
        ++NumNonAddrTakenFunctions;
198
 
      }
199
 
      Readers.clear(); Writers.clear();
200
 
    }
201
 
 
202
 
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
203
 
       I != E; ++I)
204
 
    if (I->hasLocalLinkage()) {
205
 
      if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
206
 
        // Remember that we are tracking this global, and the mod/ref fns
207
 
        NonAddressTakenGlobals.insert(I);
208
 
 
209
 
        for (unsigned i = 0, e = Readers.size(); i != e; ++i)
210
 
          FunctionInfo[Readers[i]].GlobalInfo[I] |= Ref;
211
 
 
212
 
        if (!I->isConstant())  // No need to keep track of writers to constants
213
 
          for (unsigned i = 0, e = Writers.size(); i != e; ++i)
214
 
            FunctionInfo[Writers[i]].GlobalInfo[I] |= Mod;
215
 
        ++NumNonAddrTakenGlobalVars;
216
 
 
217
 
        // If this global holds a pointer type, see if it is an indirect global.
218
 
        if (I->getType()->getElementType()->isPointerTy() &&
219
 
            AnalyzeIndirectGlobalMemory(I))
220
 
          ++NumIndirectGlobalVars;
221
 
      }
222
 
      Readers.clear(); Writers.clear();
223
 
    }
224
 
}
225
 
 
226
 
/// AnalyzeUsesOfPointer - Look at all of the users of the specified pointer.
227
 
/// If this is used by anything complex (i.e., the address escapes), return
228
 
/// true.  Also, while we are at it, keep track of those functions that read and
229
 
/// write to the value.
230
 
///
231
 
/// If OkayStoreDest is non-null, stores into this global are allowed.
232
 
bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
233
 
                                         std::vector<Function*> &Readers,
234
 
                                         std::vector<Function*> &Writers,
235
 
                                         GlobalValue *OkayStoreDest) {
236
 
  if (!V->getType()->isPointerTy()) return true;
237
 
 
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)) {
241
 
      Readers.push_back(LI->getParent()->getParent());
242
 
    } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
243
 
      if (V == SI->getOperand(1)) {
244
 
        Writers.push_back(SI->getParent()->getParent());
245
 
      } else if (SI->getOperand(1) != OkayStoreDest) {
246
 
        return true;  // Storing the pointer
247
 
      }
248
 
    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
249
 
      if (AnalyzeUsesOfPointer(GEP, Readers, Writers)) return true;
250
 
    } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
251
 
      if (AnalyzeUsesOfPointer(BCI, Readers, Writers, OkayStoreDest))
252
 
        return true;
253
 
    } else if (isFreeCall(U)) {
254
 
      Writers.push_back(cast<Instruction>(U)->getParent()->getParent());
255
 
    } else if (CallInst *CI = dyn_cast<CallInst>(U)) {
256
 
      // Make sure that this is just the function being called, not that it is
257
 
      // passing into the function.
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)) {
261
 
      // Make sure that this is just the function being called, not that it is
262
 
      // passing into the function.
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)) {
266
 
      if (CE->getOpcode() == Instruction::GetElementPtr ||
267
 
          CE->getOpcode() == Instruction::BitCast) {
268
 
        if (AnalyzeUsesOfPointer(CE, Readers, Writers))
269
 
          return true;
270
 
      } else {
271
 
        return true;
272
 
      }
273
 
    } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(U)) {
274
 
      if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
275
 
        return true;  // Allow comparison against null.
276
 
    } else {
277
 
      return true;
278
 
    }
279
 
  }
280
 
 
281
 
  return false;
282
 
}
283
 
 
284
 
/// AnalyzeIndirectGlobalMemory - We found an non-address-taken global variable
285
 
/// which holds a pointer type.  See if the global always points to non-aliased
286
 
/// heap memory: that is, all initializers of the globals are allocations, and
287
 
/// those allocations have no use other than initialization of the global.
288
 
/// Further, all loads out of GV must directly use the memory, not store the
289
 
/// pointer somewhere.  If this is true, we consider the memory pointed to by
290
 
/// GV to be owned by GV and can disambiguate other pointers from it.
291
 
bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
292
 
  // Keep track of values related to the allocation of the memory, f.e. the
293
 
  // value produced by the malloc call and any casts.
294
 
  std::vector<Value*> AllocRelatedValues;
295
 
 
296
 
  // Walk the user list of the global.  If we find anything other than a direct
297
 
  // load or store, bail out.
298
 
  for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I){
299
 
    User *U = *I;
300
 
    if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
301
 
      // The pointer loaded from the global can only be used in simple ways:
302
 
      // we allow addressing of it and loading storing to it.  We do *not* allow
303
 
      // storing the loaded pointer somewhere else or passing to a function.
304
 
      std::vector<Function*> ReadersWriters;
305
 
      if (AnalyzeUsesOfPointer(LI, ReadersWriters, ReadersWriters))
306
 
        return false;  // Loaded pointer escapes.
307
 
      // TODO: Could try some IP mod/ref of the loaded pointer.
308
 
    } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
309
 
      // Storing the global itself.
310
 
      if (SI->getOperand(0) == GV) return false;
311
 
 
312
 
      // If storing the null pointer, ignore it.
313
 
      if (isa<ConstantPointerNull>(SI->getOperand(0)))
314
 
        continue;
315
 
 
316
 
      // Check the value being stored.
317
 
      Value *Ptr = SI->getOperand(0)->getUnderlyingObject();
318
 
 
319
 
      if (isMalloc(Ptr)) {
320
 
        // Okay, easy case.
321
 
      } else if (CallInst *CI = dyn_cast<CallInst>(Ptr)) {
322
 
        Function *F = CI->getCalledFunction();
323
 
        if (!F || !F->isDeclaration()) return false;     // Too hard to analyze.
324
 
        if (F->getName() != "calloc") return false;   // Not calloc.
325
 
      } else {
326
 
        return false;  // Too hard to analyze.
327
 
      }
328
 
 
329
 
      // Analyze all uses of the allocation.  If any of them are used in a
330
 
      // non-simple way (e.g. stored to another global) bail out.
331
 
      std::vector<Function*> ReadersWriters;
332
 
      if (AnalyzeUsesOfPointer(Ptr, ReadersWriters, ReadersWriters, GV))
333
 
        return false;  // Loaded pointer escapes.
334
 
 
335
 
      // Remember that this allocation is related to the indirect global.
336
 
      AllocRelatedValues.push_back(Ptr);
337
 
    } else {
338
 
      // Something complex, bail out.
339
 
      return false;
340
 
    }
341
 
  }
342
 
 
343
 
  // Okay, this is an indirect global.  Remember all of the allocations for
344
 
  // this global in AllocsForIndirectGlobals.
345
 
  while (!AllocRelatedValues.empty()) {
346
 
    AllocsForIndirectGlobals[AllocRelatedValues.back()] = GV;
347
 
    AllocRelatedValues.pop_back();
348
 
  }
349
 
  IndirectGlobals.insert(GV);
350
 
  return true;
351
 
}
352
 
 
353
 
/// AnalyzeCallGraph - At this point, we know the functions where globals are
354
 
/// immediately stored to and read from.  Propagate this information up the call
355
 
/// graph to all callers and compute the mod/ref info for all memory for each
356
 
/// function.
357
 
void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
358
 
  // We do a bottom-up SCC traversal of the call graph.  In other words, we
359
 
  // visit all callees before callers (leaf-first).
360
 
  for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG); I != E;
361
 
       ++I) {
362
 
    std::vector<CallGraphNode *> &SCC = *I;
363
 
    assert(!SCC.empty() && "SCC with no functions?");
364
 
 
365
 
    if (!SCC[0]->getFunction()) {
366
 
      // Calls externally - can't say anything useful.  Remove any existing
367
 
      // function records (may have been created when scanning globals).
368
 
      for (unsigned i = 0, e = SCC.size(); i != e; ++i)
369
 
        FunctionInfo.erase(SCC[i]->getFunction());
370
 
      continue;
371
 
    }
372
 
 
373
 
    FunctionRecord &FR = FunctionInfo[SCC[0]->getFunction()];
374
 
 
375
 
    bool KnowNothing = false;
376
 
    unsigned FunctionEffect = 0;
377
 
 
378
 
    // Collect the mod/ref properties due to called functions.  We only compute
379
 
    // one mod-ref set.
380
 
    for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) {
381
 
      Function *F = SCC[i]->getFunction();
382
 
      if (!F) {
383
 
        KnowNothing = true;
384
 
        break;
385
 
      }
386
 
 
387
 
      if (F->isDeclaration()) {
388
 
        // Try to get mod/ref behaviour from function attributes.
389
 
        if (F->doesNotAccessMemory()) {
390
 
          // Can't do better than that!
391
 
        } else if (F->onlyReadsMemory()) {
392
 
          FunctionEffect |= Ref;
393
 
          if (!F->isIntrinsic())
394
 
            // This function might call back into the module and read a global -
395
 
            // consider every global as possibly being read by this function.
396
 
            FR.MayReadAnyGlobal = true;
397
 
        } else {
398
 
          FunctionEffect |= ModRef;
399
 
          // Can't say anything useful unless it's an intrinsic - they don't
400
 
          // read or write global variables of the kind considered here.
401
 
          KnowNothing = !F->isIntrinsic();
402
 
        }
403
 
        continue;
404
 
      }
405
 
 
406
 
      for (CallGraphNode::iterator CI = SCC[i]->begin(), E = SCC[i]->end();
407
 
           CI != E && !KnowNothing; ++CI)
408
 
        if (Function *Callee = CI->second->getFunction()) {
409
 
          if (FunctionRecord *CalleeFR = getFunctionInfo(Callee)) {
410
 
            // Propagate function effect up.
411
 
            FunctionEffect |= CalleeFR->FunctionEffect;
412
 
 
413
 
            // Incorporate callee's effects on globals into our info.
414
 
            for (std::map<const GlobalValue*, unsigned>::iterator GI =
415
 
                   CalleeFR->GlobalInfo.begin(), E = CalleeFR->GlobalInfo.end();
416
 
                 GI != E; ++GI)
417
 
              FR.GlobalInfo[GI->first] |= GI->second;
418
 
            FR.MayReadAnyGlobal |= CalleeFR->MayReadAnyGlobal;
419
 
          } else {
420
 
            // Can't say anything about it.  However, if it is inside our SCC,
421
 
            // then nothing needs to be done.
422
 
            CallGraphNode *CalleeNode = CG[Callee];
423
 
            if (std::find(SCC.begin(), SCC.end(), CalleeNode) == SCC.end())
424
 
              KnowNothing = true;
425
 
          }
426
 
        } else {
427
 
          KnowNothing = true;
428
 
        }
429
 
    }
430
 
 
431
 
    // If we can't say anything useful about this SCC, remove all SCC functions
432
 
    // from the FunctionInfo map.
433
 
    if (KnowNothing) {
434
 
      for (unsigned i = 0, e = SCC.size(); i != e; ++i)
435
 
        FunctionInfo.erase(SCC[i]->getFunction());
436
 
      continue;
437
 
    }
438
 
 
439
 
    // Scan the function bodies for explicit loads or stores.
440
 
    for (unsigned i = 0, e = SCC.size(); i != e && FunctionEffect != ModRef;++i)
441
 
      for (inst_iterator II = inst_begin(SCC[i]->getFunction()),
442
 
             E = inst_end(SCC[i]->getFunction());
443
 
           II != E && FunctionEffect != ModRef; ++II)
444
 
        if (isa<LoadInst>(*II)) {
445
 
          FunctionEffect |= Ref;
446
 
          if (cast<LoadInst>(*II).isVolatile())
447
 
            // Volatile loads may have side-effects, so mark them as writing
448
 
            // memory (for example, a flag inside the processor).
449
 
            FunctionEffect |= Mod;
450
 
        } else if (isa<StoreInst>(*II)) {
451
 
          FunctionEffect |= Mod;
452
 
          if (cast<StoreInst>(*II).isVolatile())
453
 
            // Treat volatile stores as reading memory somewhere.
454
 
            FunctionEffect |= Ref;
455
 
        } else if (isMalloc(&cast<Instruction>(*II)) ||
456
 
                   isFreeCall(&cast<Instruction>(*II))) {
457
 
          FunctionEffect |= ModRef;
458
 
        }
459
 
 
460
 
    if ((FunctionEffect & Mod) == 0)
461
 
      ++NumReadMemFunctions;
462
 
    if (FunctionEffect == 0)
463
 
      ++NumNoMemFunctions;
464
 
    FR.FunctionEffect = FunctionEffect;
465
 
 
466
 
    // Finally, now that we know the full effect on this SCC, clone the
467
 
    // information to each function in the SCC.
468
 
    for (unsigned i = 1, e = SCC.size(); i != e; ++i)
469
 
      FunctionInfo[SCC[i]->getFunction()] = FR;
470
 
  }
471
 
}
472
 
 
473
 
 
474
 
 
475
 
/// alias - If one of the pointers is to a global that we are tracking, and the
476
 
/// other is some random pointer, we know there cannot be an alias, because the
477
 
/// address of the global isn't taken.
478
 
AliasAnalysis::AliasResult
479
 
GlobalsModRef::alias(const Value *V1, unsigned V1Size,
480
 
                     const Value *V2, unsigned V2Size) {
481
 
  // Get the base object these pointers point to.
482
 
  const Value *UV1 = V1->getUnderlyingObject();
483
 
  const Value *UV2 = V2->getUnderlyingObject();
484
 
 
485
 
  // If either of the underlying values is a global, they may be non-addr-taken
486
 
  // globals, which we can answer queries about.
487
 
  const GlobalValue *GV1 = dyn_cast<GlobalValue>(UV1);
488
 
  const GlobalValue *GV2 = dyn_cast<GlobalValue>(UV2);
489
 
  if (GV1 || GV2) {
490
 
    // If the global's address is taken, pretend we don't know it's a pointer to
491
 
    // the global.
492
 
    if (GV1 && !NonAddressTakenGlobals.count(GV1)) GV1 = 0;
493
 
    if (GV2 && !NonAddressTakenGlobals.count(GV2)) GV2 = 0;
494
 
 
495
 
    // If the two pointers are derived from two different non-addr-taken
496
 
    // globals, or if one is and the other isn't, we know these can't alias.
497
 
    if ((GV1 || GV2) && GV1 != GV2)
498
 
      return NoAlias;
499
 
 
500
 
    // Otherwise if they are both derived from the same addr-taken global, we
501
 
    // can't know the two accesses don't overlap.
502
 
  }
503
 
 
504
 
  // These pointers may be based on the memory owned by an indirect global.  If
505
 
  // so, we may be able to handle this.  First check to see if the base pointer
506
 
  // is a direct load from an indirect global.
507
 
  GV1 = GV2 = 0;
508
 
  if (const LoadInst *LI = dyn_cast<LoadInst>(UV1))
509
 
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
510
 
      if (IndirectGlobals.count(GV))
511
 
        GV1 = GV;
512
 
  if (const LoadInst *LI = dyn_cast<LoadInst>(UV2))
513
 
    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
514
 
      if (IndirectGlobals.count(GV))
515
 
        GV2 = GV;
516
 
 
517
 
  // These pointers may also be from an allocation for the indirect global.  If
518
 
  // so, also handle them.
519
 
  if (AllocsForIndirectGlobals.count(UV1))
520
 
    GV1 = AllocsForIndirectGlobals[UV1];
521
 
  if (AllocsForIndirectGlobals.count(UV2))
522
 
    GV2 = AllocsForIndirectGlobals[UV2];
523
 
 
524
 
  // Now that we know whether the two pointers are related to indirect globals,
525
 
  // use this to disambiguate the pointers.  If either pointer is based on an
526
 
  // indirect global and if they are not both based on the same indirect global,
527
 
  // they cannot alias.
528
 
  if ((GV1 || GV2) && GV1 != GV2)
529
 
    return NoAlias;
530
 
 
531
 
  return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
532
 
}
533
 
 
534
 
AliasAnalysis::ModRefResult
535
 
GlobalsModRef::getModRefInfo(ImmutableCallSite CS,
536
 
                             const Value *P, unsigned Size) {
537
 
  unsigned Known = ModRef;
538
 
 
539
 
  // If we are asking for mod/ref info of a direct call with a pointer to a
540
 
  // global we are tracking, return information if we have it.
541
 
  if (const GlobalValue *GV = dyn_cast<GlobalValue>(P->getUnderlyingObject()))
542
 
    if (GV->hasLocalLinkage())
543
 
      if (const Function *F = CS.getCalledFunction())
544
 
        if (NonAddressTakenGlobals.count(GV))
545
 
          if (const FunctionRecord *FR = getFunctionInfo(F))
546
 
            Known = FR->getInfoForGlobal(GV);
547
 
 
548
 
  if (Known == NoModRef)
549
 
    return NoModRef; // No need to query other mod/ref analyses
550
 
  return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, P, Size));
551
 
}
552
 
 
553
 
 
554
 
//===----------------------------------------------------------------------===//
555
 
// Methods to update the analysis as a result of the client transformation.
556
 
//
557
 
void GlobalsModRef::deleteValue(Value *V) {
558
 
  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
559
 
    if (NonAddressTakenGlobals.erase(GV)) {
560
 
      // This global might be an indirect global.  If so, remove it and remove
561
 
      // any AllocRelatedValues for it.
562
 
      if (IndirectGlobals.erase(GV)) {
563
 
        // Remove any entries in AllocsForIndirectGlobals for this global.
564
 
        for (std::map<const Value*, const GlobalValue*>::iterator
565
 
             I = AllocsForIndirectGlobals.begin(),
566
 
             E = AllocsForIndirectGlobals.end(); I != E; ) {
567
 
          if (I->second == GV) {
568
 
            AllocsForIndirectGlobals.erase(I++);
569
 
          } else {
570
 
            ++I;
571
 
          }
572
 
        }
573
 
      }
574
 
    }
575
 
  }
576
 
 
577
 
  // Otherwise, if this is an allocation related to an indirect global, remove
578
 
  // it.
579
 
  AllocsForIndirectGlobals.erase(V);
580
 
 
581
 
  AliasAnalysis::deleteValue(V);
582
 
}
583
 
 
584
 
void GlobalsModRef::copyValue(Value *From, Value *To) {
585
 
  AliasAnalysis::copyValue(From, To);
586
 
}