//===- 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
// that do not have their address taken, and keeps track of whether functions
// read or write memory (are "pure").  For this simple (but very common) case,
// we can provide pretty accurate and useful information.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "globalsmodref-aa"
#include "llvm/Analysis/Passes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Instructions.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CallGraph.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 {
  /// 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 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.
    std::map<GlobalValue*, unsigned> GlobalInfo;

    unsigned getInfoForGlobal(GlobalValue *GV) const {
      std::map<GlobalValue*, unsigned>::const_iterator I = GlobalInfo.find(GV);
      if (I != GlobalInfo.end())
        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;

    FunctionRecord() : FunctionEffect(0) {}
  };

  /// GlobalsModRef - The actual analysis pass.
  class VISIBILITY_HIDDEN GlobalsModRef 
      : public ModulePass, public AliasAnalysis {
    /// NonAddressTakenGlobals - The globals that do not have their addresses
    /// taken.
    std::set<GlobalValue*> NonAddressTakenGlobals;

    /// IndirectGlobals - The memory pointed to by this global is known to be
    /// 'owned' by the global.
    std::set<GlobalValue*> IndirectGlobals;
    
    /// AllocsForIndirectGlobals - If an instruction allocates memory for an
    /// indirect global, this map indicates which one.
    std::map<Value*, GlobalValue*> AllocsForIndirectGlobals;
    
    /// FunctionInfo - For each function, keep track of what globals are
    /// modified or read.
    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
      AnalyzeCallGraph(getAnalysis<CallGraph>(), M); // Propagate on CG
      return false;
    }

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AliasAnalysis::getAnalysisUsage(AU);
      AU.addRequired<CallGraph>();
      AU.setPreservesAll();                         // Does not transform code
    }

    //------------------------------------------------
    // Implement the AliasAnalysis API
    //
    AliasResult alias(const Value *V1, unsigned V1Size,
                      const Value *V2, unsigned V2Size);
    ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
    ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
      return AliasAnalysis::getModRefInfo(CS1,CS2);
    }
    bool hasNoModRefInfoForCalls() const { return false; }

    /// getModRefBehavior - Return the behavior of the specified function if
    /// called from the specified call site.  The call site may be null in which
    /// case the most generic behavior of this function should be returned.
    virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
                                         std::vector<PointerAccessInfo> *Info) {
      if (FunctionRecord *FR = getFunctionInfo(F))
        if (FR->FunctionEffect == 0)
          return DoesNotAccessMemory;
        else if ((FR->FunctionEffect & Mod) == 0)
          return OnlyReadsMemory;
      return AliasAnalysis::getModRefBehavior(F, CS, Info);
    }

    virtual void deleteValue(Value *V);
    virtual void copyValue(Value *From, Value *To);

  private:
    /// getFunctionInfo - Return the function info for the function, or null if
    /// the function calls an external function (in which case we don't have
    /// anything useful to say about it).
    FunctionRecord *getFunctionInfo(Function *F) {
      std::map<Function*, FunctionRecord>::iterator I = FunctionInfo.find(F);
      if (I != FunctionInfo.end())
        return &I->second;
      return 0;
    }

    void AnalyzeGlobals(Module &M);
    void AnalyzeCallGraph(CallGraph &CG, Module &M);
    void AnalyzeSCC(std::vector<CallGraphNode *> &SCC);
    bool AnalyzeUsesOfPointer(Value *V, std::vector<Function*> &Readers,
                              std::vector<Function*> &Writers,
                              GlobalValue *OkayStoreDest = 0);
    bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
  };

  char GlobalsModRef::ID = 0;
  RegisterPass<GlobalsModRef> X("globalsmodref-aa",
                                "Simple mod/ref analysis for globals");
  RegisterAnalysisGroup<AliasAnalysis> Y(X);
}

Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }

/// getUnderlyingObject - This traverses the use chain to figure out what object
/// the specified value points to.  If the value points to, or is derived from,
/// a global object, return it.
static Value *getUnderlyingObject(Value *V) {
  if (!isa<PointerType>(V->getType())) return V;
  
  // If we are at some type of object... return it.
  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV;
  
  // Traverse through different addressing mechanisms.
  if (Instruction *I = dyn_cast<Instruction>(V)) {
    if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
      return getUnderlyingObject(I->getOperand(0));
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
    if (CE->getOpcode() == Instruction::BitCast || 
        CE->getOpcode() == Instruction::GetElementPtr)
      return getUnderlyingObject(CE->getOperand(0));
  }
  
  // Othewise, we don't know what this is, return it as the base pointer.
  return V;
}

/// AnalyzeGlobals - Scan through the users of all of the internal
/// GlobalValue's in the program.  If none of them have their "Address taken"
/// (really, their address passed to something nontrivial), record this fact,
/// and record the functions that they are used directly in.
void GlobalsModRef::AnalyzeGlobals(Module &M) {
  std::vector<Function*> Readers, Writers;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (I->hasInternalLinkage()) {
      if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
        // Remember that we are tracking this global.
        NonAddressTakenGlobals.insert(I);
        ++NumNonAddrTakenFunctions;
      }
      Readers.clear(); Writers.clear();
    }

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (I->hasInternalLinkage()) {
      if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
        // Remember that we are tracking this global, and the mod/ref fns
        NonAddressTakenGlobals.insert(I);
        for (unsigned i = 0, e = Readers.size(); i != e; ++i)
          FunctionInfo[Readers[i]].GlobalInfo[I] |= Ref;

        if (!I->isConstant())  // No need to keep track of writers to constants
          for (unsigned i = 0, e = Writers.size(); i != e; ++i)
            FunctionInfo[Writers[i]].GlobalInfo[I] |= Mod;
        ++NumNonAddrTakenGlobalVars;
        
        // If this global holds a pointer type, see if it is an indirect global.
        if (isa<PointerType>(I->getType()->getElementType()) &&
            AnalyzeIndirectGlobalMemory(I))
          ++NumIndirectGlobalVars;
      }
      Readers.clear(); Writers.clear();
    }
}

/// AnalyzeUsesOfPointer - Look at all of the users of the specified pointer.
/// If this is used by anything complex (i.e., the address escapes), return
/// true.  Also, while we are at it, keep track of those functions that read and
/// write to the value.
///
/// If OkayStoreDest is non-null, stores into this global are allowed.
bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
                                         std::vector<Function*> &Readers,
                                         std::vector<Function*> &Writers,
                                         GlobalValue *OkayStoreDest) {
  if (!isa<PointerType>(V->getType())) return true;

  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
    if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
      Readers.push_back(LI->getParent()->getParent());
    } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
      if (V == SI->getOperand(1)) {
        Writers.push_back(SI->getParent()->getParent());
      } else if (SI->getOperand(1) != OkayStoreDest) {
        return true;  // Storing the pointer
      }
    } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*UI)) {
      if (AnalyzeUsesOfPointer(GEP, Readers, Writers)) 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.
      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::BitCast) {
        if (AnalyzeUsesOfPointer(CE, Readers, Writers))
          return true;
      } else {
        return true;
      }
    } 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());
    } else {
      return true;
    }
  return false;
}

/// AnalyzeIndirectGlobalMemory - We found an non-address-taken global variable
/// which holds a pointer type.  See if the global always points to non-aliased
/// heap memory: that is, all initializers of the globals are allocations, and
/// those allocations have no use other than initialization of the global.
/// Further, all loads out of GV must directly use the memory, not store the
/// pointer somewhere.  If this is true, we consider the memory pointed to by
/// GV to be owned by GV and can disambiguate other pointers from it.
bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
  // Keep track of values related to the allocation of the memory, f.e. the
  // value produced by the malloc call and any casts.
  std::vector<Value*> AllocRelatedValues;
  
  // Walk the user list of the global.  If we find anything other than a direct
  // load or store, bail out.
  for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I){
    if (LoadInst *LI = dyn_cast<LoadInst>(*I)) {
      // The pointer loaded from the global can only be used in simple ways:
      // we allow addressing of it and loading storing to it.  We do *not* allow
      // storing the loaded pointer somewhere else or passing to a function.
      std::vector<Function*> ReadersWriters;
      if (AnalyzeUsesOfPointer(LI, ReadersWriters, ReadersWriters))
        return false;  // Loaded pointer escapes.
      // TODO: Could try some IP mod/ref of the loaded pointer.
    } else if (StoreInst *SI = dyn_cast<StoreInst>(*I)) {
      // Storing the global itself.
      if (SI->getOperand(0) == GV) return false;
      
      // If storing the null pointer, ignore it.
      if (isa<ConstantPointerNull>(SI->getOperand(0)))
        continue;
      
      // Check the value being stored.
      Value *Ptr = getUnderlyingObject(SI->getOperand(0));

      if (isa<MallocInst>(Ptr)) {
        // Okay, easy case.
      } else if (CallInst *CI = dyn_cast<CallInst>(Ptr)) {
        Function *F = CI->getCalledFunction();
        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.
      }
      
      // Analyze all uses of the allocation.  If any of them are used in a
      // non-simple way (e.g. stored to another global) bail out.
      std::vector<Function*> ReadersWriters;
      if (AnalyzeUsesOfPointer(Ptr, ReadersWriters, ReadersWriters, GV))
        return false;  // Loaded pointer escapes.

      // Remember that this allocation is related to the indirect global.
      AllocRelatedValues.push_back(Ptr);
    } else {
      // Something complex, bail out.
      return false;
    }
  }
  
  // Okay, this is an indirect global.  Remember all of the allocations for
  // this global in AllocsForIndirectGlobals.
  while (!AllocRelatedValues.empty()) {
    AllocsForIndirectGlobals[AllocRelatedValues.back()] = GV;
    AllocRelatedValues.pop_back();
  }
  IndirectGlobals.insert(GV);
  return true;
}

/// 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.
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).
  for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG); I!=E; ++I)
    if ((*I).size() != 1) {
      AnalyzeSCC(*I);
    } else if (Function *F = (*I)[0]->getFunction()) {
      if (!F->isDeclaration()) {
        // Nonexternal function.
        AnalyzeSCC(*I);
      } else {
        // Otherwise external function.  Handle intrinsics and other special
        // cases here.
        if (getAnalysis<AliasAnalysis>().doesNotAccessMemory(F))
          // If it does not access memory, process the function, causing us to
          // realize it doesn't do anything (the body is empty).
          AnalyzeSCC(*I);
        else {
          // Otherwise, don't process it.  This will cause us to conservatively
          // assume the worst.
        }
      }
    } else {
      // Do not process the external node, assume the worst.
    }
}

void GlobalsModRef::AnalyzeSCC(std::vector<CallGraphNode *> &SCC) {
  assert(!SCC.empty() && "SCC with no functions?");
  FunctionRecord &FR = FunctionInfo[SCC[0]->getFunction()];

  bool CallsExternal = false;
  unsigned FunctionEffect = 0;

  // Collect the mod/ref properties due to called functions.  We only compute
  // one mod-ref set
  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->second->getFunction()) {
        if (FunctionRecord *CalleeFR = getFunctionInfo(Callee)) {
          // Propagate function effect up.
          FunctionEffect |= CalleeFR->FunctionEffect;

          // Incorporate callee's effects on globals into our info.
          for (std::map<GlobalValue*, unsigned>::iterator GI =
                 CalleeFR->GlobalInfo.begin(), E = CalleeFR->GlobalInfo.end();
               GI != E; ++GI)
            FR.GlobalInfo[GI->first] |= GI->second;

        } else {
          // 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;
        break;
      }

  // If this SCC calls an external function, we can't say anything about it, so
  // remove all SCC functions from the FunctionInfo map.
  if (CallsExternal) {
    for (unsigned i = 0, e = SCC.size(); i != e; ++i)
      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());
           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)
    ++NumReadMemFunctions;
  if (FunctionEffect == 0)
    ++NumNoMemFunctions;
  FR.FunctionEffect = FunctionEffect;

  // Finally, now that we know the full effect on this SCC, clone the
  // information to each function in the SCC.
  for (unsigned i = 1, e = SCC.size(); i != e; ++i)
    FunctionInfo[SCC[i]->getFunction()] = FR;
}



/// alias - If one of the pointers is to a global that we are tracking, and the
/// other is some random pointer, we know there cannot be an alias, because the
/// address of the global isn't taken.
AliasAnalysis::AliasResult
GlobalsModRef::alias(const Value *V1, unsigned V1Size,
                     const Value *V2, unsigned V2Size) {
  // Get the base object these pointers point to.
  Value *UV1 = getUnderlyingObject(const_cast<Value*>(V1));
  Value *UV2 = getUnderlyingObject(const_cast<Value*>(V2));
  
  // If either of the underlying values is a global, they may be non-addr-taken
  // globals, which we can answer queries about.
  GlobalValue *GV1 = dyn_cast<GlobalValue>(UV1);
  GlobalValue *GV2 = dyn_cast<GlobalValue>(UV2);
  if (GV1 || GV2) {
    // If the global's address is taken, pretend we don't know it's a pointer to
    // the global.
    if (GV1 && !NonAddressTakenGlobals.count(GV1)) GV1 = 0;
    if (GV2 && !NonAddressTakenGlobals.count(GV2)) GV2 = 0;

    // If the the two pointers are derived from two different non-addr-taken
    // globals, or if one is and the other isn't, we know these can't alias.
    if ((GV1 || GV2) && GV1 != GV2)
      return NoAlias;

    // Otherwise if they are both derived from the same addr-taken global, we
    // can't know the two accesses don't overlap.
  }
  
  // These pointers may be based on the memory owned by an indirect global.  If
  // so, we may be able to handle this.  First check to see if the base pointer
  // is a direct load from an indirect global.
  GV1 = GV2 = 0;
  if (LoadInst *LI = dyn_cast<LoadInst>(UV1))
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
      if (IndirectGlobals.count(GV))
        GV1 = GV;
  if (LoadInst *LI = dyn_cast<LoadInst>(UV2))
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
      if (IndirectGlobals.count(GV))
        GV2 = GV;
  
  // These pointers may also be from an allocation for the indirect global.  If
  // so, also handle them.
  if (AllocsForIndirectGlobals.count(UV1))
    GV1 = AllocsForIndirectGlobals[UV1];
  if (AllocsForIndirectGlobals.count(UV2))
    GV2 = AllocsForIndirectGlobals[UV2];
  
  // Now that we know whether the two pointers are related to indirect globals,
  // use this to disambiguate the pointers.  If either pointer is based on an
  // indirect global and if they are not both based on the same indirect global,
  // they cannot alias.
  if ((GV1 || GV2) && GV1 != GV2)
    return NoAlias;
  
  return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
}

AliasAnalysis::ModRefResult
GlobalsModRef::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
  unsigned Known = ModRef;

  // If we are asking for mod/ref info of a direct call with a pointer to a
  // global we are tracking, return information if we have it.
  if (GlobalValue *GV = dyn_cast<GlobalValue>(getUnderlyingObject(P)))
    if (GV->hasInternalLinkage())
      if (Function *F = CS.getCalledFunction())
        if (NonAddressTakenGlobals.count(GV))
          if (FunctionRecord *FR = getFunctionInfo(F))
            Known = FR->getInfoForGlobal(GV);

  if (Known == NoModRef)
    return NoModRef; // No need to query other mod/ref analyses
  return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, P, Size));
}


//===----------------------------------------------------------------------===//
// Methods to update the analysis as a result of the client transformation.
//
void GlobalsModRef::deleteValue(Value *V) {
  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
    if (NonAddressTakenGlobals.erase(GV)) {
      // This global might be an indirect global.  If so, remove it and remove
      // any AllocRelatedValues for it.
      if (IndirectGlobals.erase(GV)) {
        // Remove any entries in AllocsForIndirectGlobals for this global.
        for (std::map<Value*, GlobalValue*>::iterator
             I = AllocsForIndirectGlobals.begin(),
             E = AllocsForIndirectGlobals.end(); I != E; ) {
          if (I->second == GV) {
            AllocsForIndirectGlobals.erase(I++);
          } else {
            ++I;
          }
        }
      }
    }
  }
  
  // Otherwise, if this is an allocation related to an indirect global, remove
  // it.
  AllocsForIndirectGlobals.erase(V);
}

void GlobalsModRef::copyValue(Value *From, Value *To) {
}
