Remove attribution from file headers, per discussion on llvmdev.
[oota-llvm.git] / lib / Analysis / IPA / GlobalsModRef.cpp
index 5c10da552780d9daf48ee5436357f59f13e6c3a4..880298ec020d62bed1826716d36069d80004aa11 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     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 file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,6 +14,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "globalsmodref-aa"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/CallGraph.h"
-#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/InstIterator.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/SCCIterator.h"
 #include <set>
 using namespace llvm;
 
+STATISTIC(NumNonAddrTakenGlobalVars,
+          "Number of global vars without address taken");
+STATISTIC(NumNonAddrTakenFunctions,"Number of functions without address taken");
+STATISTIC(NumNoMemFunctions, "Number of functions that do not access memory");
+STATISTIC(NumReadMemFunctions, "Number of functions that only read memory");
+STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");
+
 namespace {
-  Statistic<>
-  NumNonAddrTakenGlobalVars("globalsmodref-aa",
-                            "Number of global vars without address taken");
-  Statistic<>
-  NumNonAddrTakenFunctions("globalsmodref-aa",
-                           "Number of functions without address taken");
-  Statistic<>
-  NumNoMemFunctions("globalsmodref-aa",
-                    "Number of functions that do not access memory");
-  Statistic<>
-  NumReadMemFunctions("globalsmodref-aa",
-                      "Number of functions that only read memory");
-  Statistic<>
-  NumIndirectGlobalVars("globalsmodref-aa",
-                        "Number of indirect global objects");
-  
   /// FunctionRecord - One instance of this structure is stored for every
   /// function in the program.  Later, the entries for these functions are
   /// removed if the function is found to call an external function (in which
   /// case we know nothing about it.
-  struct FunctionRecord {
+  struct VISIBILITY_HIDDEN FunctionRecord {
     /// GlobalInfo - Maintain mod/ref info for all of the globals without
     /// addresses taken that are read or written (transitively) by this
     /// function.
@@ -71,7 +64,8 @@ namespace {
   };
 
   /// GlobalsModRef - The actual analysis pass.
-  class GlobalsModRef : public ModulePass, public AliasAnalysis {
+  class VISIBILITY_HIDDEN GlobalsModRef 
+      : public ModulePass, public AliasAnalysis {
     /// NonAddressTakenGlobals - The globals that do not have their addresses
     /// taken.
     std::set<GlobalValue*> NonAddressTakenGlobals;
@@ -89,6 +83,9 @@ namespace {
     std::map<Function*, FunctionRecord> FunctionInfo;
 
   public:
+    static char ID;
+    GlobalsModRef() : ModulePass((intptr_t)&ID) {}
+
     bool runOnModule(Module &M) {
       InitializeAliasAnalysis(this);                 // set up super class
       AnalyzeGlobals(M);                          // find non-addr taken globals
@@ -149,6 +146,7 @@ namespace {
     bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
   };
 
+  char GlobalsModRef::ID = 0;
   RegisterPass<GlobalsModRef> X("globalsmodref-aa",
                                 "Simple mod/ref analysis for globals");
   RegisterAnalysisGroup<AliasAnalysis> Y(X);
@@ -167,10 +165,10 @@ static Value *getUnderlyingObject(Value *V) {
   
   // Traverse through different addressing mechanisms.
   if (Instruction *I = dyn_cast<Instruction>(V)) {
-    if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
+    if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
       return getUnderlyingObject(I->getOperand(0));
   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
-    if (CE->getOpcode() == Instruction::Cast ||
+    if (CE->getOpcode() == Instruction::BitCast || 
         CE->getOpcode() == Instruction::GetElementPtr)
       return getUnderlyingObject(CE->getOperand(0));
   }
@@ -252,15 +250,15 @@ bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
       for (unsigned i = 3, e = II->getNumOperands(); i != e; ++i)
         if (II->getOperand(i) == V) return true;
     } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
-      if (CE->getOpcode() == Instruction::GetElementPtr ||
-          CE->getOpcode() == Instruction::Cast) {
+      if (CE->getOpcode() == Instruction::GetElementPtr || 
+          CE->getOpcode() == Instruction::BitCast) {
         if (AnalyzeUsesOfPointer(CE, Readers, Writers))
           return true;
       } else {
         return true;
       }
-    } else if (SetCondInst *SCI = dyn_cast<SetCondInst>(*UI)) {
-      if (!isa<ConstantPointerNull>(SCI->getOperand(1)))
+    } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
+      if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
         return true;  // Allow comparison against null.
     } else if (FreeInst *F = dyn_cast<FreeInst>(*UI)) {
       Writers.push_back(F->getParent()->getParent());
@@ -304,12 +302,11 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
       // Check the value being stored.
       Value *Ptr = getUnderlyingObject(SI->getOperand(0));
 
-      // FIXME: handle calloc.
       if (isa<MallocInst>(Ptr)) {
         // Okay, easy case.
       } else if (CallInst *CI = dyn_cast<CallInst>(Ptr)) {
         Function *F = CI->getCalledFunction();
-        if (!F || !F->isExternal()) return false;     // Too hard to analyze.
+        if (!F || !F->isDeclaration()) return false;     // Too hard to analyze.
         if (F->getName() != "calloc") return false;   // Not calloc.
       } else {
         return false;  // Too hard to analyze.
@@ -350,7 +347,7 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
     if ((*I).size() != 1) {
       AnalyzeSCC(*I);
     } else if (Function *F = (*I)[0]->getFunction()) {
-      if (!F->isExternal()) {
+      if (!F->isDeclaration()) {
         // Nonexternal function.
         AnalyzeSCC(*I);
       } else {
@@ -397,7 +394,7 @@ void GlobalsModRef::AnalyzeSCC(std::vector<CallGraphNode *> &SCC) {
           // Okay, if we can't say anything about it, maybe some other alias
           // analysis can.
           ModRefBehavior MRB =
-            AliasAnalysis::getModRefBehavior(Callee, CallSite());
+            AliasAnalysis::getModRefBehavior(Callee);
           if (MRB != DoesNotAccessMemory) {
             // FIXME: could make this more aggressive for functions that just
             // read memory.  We should just say they read all globals.
@@ -551,7 +548,10 @@ void GlobalsModRef::deleteValue(Value *V) {
   // Otherwise, if this is an allocation related to an indirect global, remove
   // it.
   AllocsForIndirectGlobals.erase(V);
+  
+  AliasAnalysis::deleteValue(V);
 }
 
 void GlobalsModRef::copyValue(Value *From, Value *To) {
+  AliasAnalysis::copyValue(From, To);
 }