Eliminate RegisterAnalysis. RegisterPass now does all that is necessary.
[oota-llvm.git] / lib / Analysis / IPA / GlobalsModRef.cpp
index 4a97a8f037465d6cd55434b2587de745436230d5..4765b096b38777bf5e07d1e6817168b61f877cda 100644 (file)
@@ -1,10 +1,10 @@
 //===- GlobalsModRef.cpp - Simple Mod/Ref Analysis for Globals ------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This simple pass provides alias and mod/ref information for global values
@@ -58,7 +58,7 @@ namespace {
         return I->second;
       return 0;
     }
-    
+
     /// FunctionEffect - Capture whether or not this function reads or writes to
     /// ANY memory.  If not, we can do a lot of aggressive analysis on it.
     unsigned FunctionEffect;
@@ -92,7 +92,7 @@ namespace {
 
     //------------------------------------------------
     // Implement the AliasAnalysis API
-    //  
+    //
     AliasResult alias(const Value *V1, unsigned V1Size,
                       const Value *V2, unsigned V2Size);
     ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
@@ -109,9 +109,9 @@ namespace {
       if (FunctionRecord *FR = getFunctionInfo(F))
         if (FR->FunctionEffect == 0)
           return DoesNotAccessMemory;
-       else if ((FR->FunctionEffect & Mod) == 0)
-         return OnlyReadsMemory;
-      return AliasAnalysis::getModRefBehavior(F, CS);    
+        else if ((FR->FunctionEffect & Mod) == 0)
+          return OnlyReadsMemory;
+      return AliasAnalysis::getModRefBehavior(F, CS, Info);
     }
 
     virtual void deleteValue(Value *V);
@@ -134,7 +134,7 @@ namespace {
     bool AnalyzeUsesOfGlobal(Value *V, std::vector<Function*> &Readers,
                              std::vector<Function*> &Writers);
   };
-  
+
   RegisterOpt<GlobalsModRef> X("globalsmodref-aa",
                                "Simple mod/ref analysis for globals");
   RegisterAnalysisGroup<AliasAnalysis, GlobalsModRef> Y;
@@ -159,7 +159,8 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
       Readers.clear(); Writers.clear();
     }
 
-  for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
     if (I->hasInternalLinkage()) {
       if (!AnalyzeUsesOfGlobal(I, Readers, Writers)) {
         // Remember that we are tracking this global, and the mod/ref fns
@@ -198,11 +199,6 @@ bool GlobalsModRef::AnalyzeUsesOfGlobal(Value *V,
       // passing into the function.
       for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
         if (CI->getOperand(i) == V) return true;
-    } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
-      // Make sure that this is just the function being called, not that it is
-      // passing into the function.
-      for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
-        if (CI->getOperand(i) == V) return true;
     } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
       // Make sure that this is just the function being called, not that it is
       // passing into the function.
@@ -215,7 +211,7 @@ bool GlobalsModRef::AnalyzeUsesOfGlobal(Value *V,
           return true;
       } else {
         return true;
-      }        
+      }
     } else if (GlobalValue *GV = dyn_cast<GlobalValue>(*UI)) {
       if (AnalyzeUsesOfGlobal(GV, Readers, Writers)) return true;
     } else {
@@ -227,7 +223,7 @@ bool GlobalsModRef::AnalyzeUsesOfGlobal(Value *V,
 /// AnalyzeCallGraph - At this point, we know the functions where globals are
 /// immediately stored to and read from.  Propagate this information up the call
 /// graph to all callers and compute the mod/ref info for all memory for each
-/// function.  
+/// function.
 void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
   // We do a bottom-up SCC traversal of the call graph.  In other words, we
   // visit all callees before callers (leaf-first).
@@ -267,7 +263,7 @@ void GlobalsModRef::AnalyzeSCC(std::vector<CallGraphNode *> &SCC) {
   for (unsigned i = 0, e = SCC.size(); i != e && !CallsExternal; ++i)
     for (CallGraphNode::iterator CI = SCC[i]->begin(), E = SCC[i]->end();
          CI != E; ++CI)
-      if (Function *Callee = (*CI)->getFunction()) {
+      if (Function *Callee = CI->second->getFunction()) {
         if (FunctionRecord *CalleeFR = getFunctionInfo(Callee)) {
           // Propagate function effect up.
           FunctionEffect |= CalleeFR->FunctionEffect;
@@ -279,8 +275,16 @@ void GlobalsModRef::AnalyzeSCC(std::vector<CallGraphNode *> &SCC) {
             FR.GlobalInfo[GI->first] |= GI->second;
 
         } else {
-          CallsExternal = true;
-          break;
+          // Okay, if we can't say anything about it, maybe some other alias
+          // analysis can.
+          ModRefBehavior MRB =
+            AliasAnalysis::getModRefBehavior(Callee, CallSite());
+          if (MRB != DoesNotAccessMemory) {
+            // FIXME: could make this more aggressive for functions that just
+            // read memory.  We should just say they read all globals.
+            CallsExternal = true;
+            break;
+          }
         }
       } else {
         CallsExternal = true;
@@ -294,18 +298,20 @@ void GlobalsModRef::AnalyzeSCC(std::vector<CallGraphNode *> &SCC) {
       FunctionInfo.erase(SCC[i]->getFunction());
     return;
   }
-  
+
   // Otherwise, unless we already know that this function mod/refs memory, scan
   // the function bodies to see if there are any explicit loads or stores.
   if (FunctionEffect != ModRef) {
     for (unsigned i = 0, e = SCC.size(); i != e && FunctionEffect != ModRef;++i)
       for (inst_iterator II = inst_begin(SCC[i]->getFunction()),
-             E = inst_end(SCC[i]->getFunction()); 
+             E = inst_end(SCC[i]->getFunction());
            II != E && FunctionEffect != ModRef; ++II)
         if (isa<LoadInst>(*II))
           FunctionEffect |= Ref;
         else if (isa<StoreInst>(*II))
           FunctionEffect |= Mod;
+        else if (isa<MallocInst>(*II) || isa<FreeInst>(*II))
+          FunctionEffect |= ModRef;
   }
 
   if ((FunctionEffect & Mod) == 0)
@@ -330,7 +336,7 @@ static const GlobalValue *getUnderlyingObject(const Value *V) {
 
   // If we are at some type of object... return it.
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV;
-  
+
   // Traverse through different addressing mechanisms...
   if (const Instruction *I = dyn_cast<Instruction>(V)) {
     if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))