//===- Local.cpp - Compute a local data structure graph for a function ----===//
//
//                     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.
//
//===----------------------------------------------------------------------===//
//
// Compute the local version of the data structure graph for a function.  The
// external interface to this file is the DSGraph constructor.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Statistic.h"
#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
#include "poolalloc/Config/config.h"
#include <iostream>
#include <queue>

// FIXME: This should eventually be a FunctionPass that is automatically
// aggregated into a Pass.
//
#include "llvm/Module.h"

using namespace llvm;

#ifdef LLVA_KERNEL
static Statistic<> CacheAllocs ("dsa", "Number of kmem_cache_alloc calls");
static Statistic<> KMallocs    ("dsa", "Number of kmalloc calls");
static Statistic<> GlobalPools ("dsa", "Number of global pools");
std::map<unsigned int, Function*> syscalls;
#endif

static Statistic<> CastTraceT ("dsa", "Number of int casts traced successfully");
static Statistic<> CastTraceF ("dsa", "Number of int casts not traced");

Statistic<> stat_unknown ("dsa", "Number of markunknowns");
static cl::opt<bool>
Crash("dsa-crash", cl::Hidden,
         cl::desc("Crash on unknowns"));
static cl::opt<int>
CrashAt("dsa-crashat", cl::Hidden,
         cl::desc("Crash on unknowns"));
static bool DebugUnknown = true;
static int CrashCur = 0;
DSNode *DSNode::setUnknownNodeMarker() { 
  if (Crash && CrashCur == CrashAt) assert(0); 
  ++CrashCur;
  ++stat_unknown; 
  NodeType |= UnknownNode; 
  return this;
}


static RegisterPass<LocalDataStructures>
X("datastructure", "Local Data Structure Analysis");

static cl::opt<bool>
TrackIntegersAsPointers("dsa-track-integers", cl::Hidden,
         cl::desc("If this is set, track integers as potential pointers"));

static cl::list<std::string>
AllocList("dsa-alloc-list",
          cl::value_desc("list"),
          cl::desc("List of functions that allocate memory from the heap"),
          cl::CommaSeparated, cl::Hidden);

static cl::list<std::string>
IOAllocList("dsa-ioalloc-list",
          cl::value_desc("list"),
          cl::desc("List of functions that allocate memory for I/O"),
          cl::CommaSeparated, cl::Hidden);

static cl::list<std::string>
FreeList("dsa-free-list",
          cl::value_desc("list"),
          cl::desc("List of functions that free memory from the heap"),
          cl::CommaSeparated, cl::Hidden);

namespace llvm {
namespace DS {
  // isPointerType - Return true if this type is big enough to hold a pointer.
  bool isPointerType(const Type *Ty) {
    if (isa<PointerType>(Ty))
      return true;
    else if (TrackIntegersAsPointers && Ty->isPrimitiveType() &&Ty->isInteger())
      return Ty->getPrimitiveSize() >= PointerSize;
    return false;
  }
}}

using namespace DS;

namespace {
  cl::opt<bool>
  DisableDirectCallOpt("disable-direct-call-dsopt", cl::Hidden,
                       cl::desc("Disable direct call optimization in "
                                "DSGraph construction"));
  cl::opt<bool>
  DisableFieldSensitivity("disable-ds-field-sensitivity", cl::Hidden,
                          cl::desc("Disable field sensitivity in DSGraphs"));

  //===--------------------------------------------------------------------===//
  //  GraphBuilder Class
  //===--------------------------------------------------------------------===//
  //
  /// This class is the builder class that constructs the local data structure
  /// graph by performing a single pass over the function in question.
  ///
  class GraphBuilder : InstVisitor<GraphBuilder> {
    DSGraph &G;
    DSNodeHandle *RetNode;               // Node that gets returned...
    DSScalarMap &ScalarMap;
    std::list<DSCallSite> *FunctionCalls;
    Value * KMallocPool;
  public:
    GraphBuilder(Function &f, DSGraph &g, DSNodeHandle &retNode,
                 std::list<DSCallSite> &fc)
      : G(g), RetNode(&retNode), ScalarMap(G.getScalarMap()),
        FunctionCalls(&fc) {
      // Find the type unsafe pool in the program
      KMallocPool = f.getParent()->getNamedGlobal ("KmallocPool");
      
#if 1
      //
      // Determine if the function somehow escapes
      //
      bool escapes = false;
      if (!(f.hasInternalLinkage())) {
        escapes = true;
      }
      Value::use_iterator U;
      for (U=f.use_begin(); U != f.use_end(); ++U) {
        if (isa<GlobalValue>(U)) {
          //          std::cerr << "LLVA: isa: " << f.getName() << " " << *U << std::endl;
          escapes = true;
          break;
        }
      }
#endif
      // Create scalar nodes for all pointer arguments...
      for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end();
           I != E; ++I) {
        if (isPointerType(I->getType())) {
          DSNode * Node = getValueDest(*I).getNode();
          if (!(f.hasInternalLinkage())) {
            Node->setExternalMarker();
          }
        }
      }

      visit(f);  // Single pass over the function
#if 0
std::cerr << "LLVA: Function " << f.getName() << "\n";
      for (DSScalarMap::iterator I = ScalarMap.begin(), E=ScalarMap.end();
           I != E;
           ++I)
      {
        std::cerr << "LLVA:\t" << I->first->getName() << ": " << (void *)(I->second.getNode()) << "\n";
      }
#endif
    }

    // GraphBuilder ctor for working on the globals graph
    GraphBuilder(DSGraph &g)
      : G(g), RetNode(0), ScalarMap(G.getScalarMap()), FunctionCalls(0) {
    }
    void mergeInGlobalInitializer(GlobalVariable *GV);

  private:
    // Visitor functions, used to handle each instruction type we encounter...
    friend class InstVisitor<GraphBuilder>;
    void visitMallocInst(MallocInst &MI) { handleAlloc(MI, true); }
    void visitAllocaInst(AllocaInst &AI) { handleAlloc(AI, false); }
    void handleAlloc(AllocationInst &AI, bool isHeap);

    void visitPHINode(PHINode &PN);
    void visitSelectInst(SelectInst &SI);

    void visitGetElementPtrInst(User &GEP);
    void visitReturnInst(ReturnInst &RI);
    void visitLoadInst(LoadInst &LI);
    void visitStoreInst(StoreInst &SI);
    void visitCallInst(CallInst &CI);
    void visitInvokeInst(InvokeInst &II);
    void visitSetCondInst(SetCondInst &SCI);
    void visitFreeInst(FreeInst &FI);
    void visitCastInst(CastInst &CI);
    void visitInstruction(Instruction &I);

    bool visitIntrinsic(CallSite CS, Function* F);
    bool visitExternal(CallSite CS, Function* F);
    void visitCallSite(CallSite CS);
    void visitVAArgInst(VAArgInst   &I);

    void MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C);
  private:
    // Helper functions used to implement the visitation functions...

    /// createNode - Create a new DSNode, ensuring that it is properly added to
    /// the graph.
    ///
    DSNode *createNode(const Type *Ty = 0) {
      DSNode *N = new DSNode(Ty, &G);   // Create the node
      if (DisableFieldSensitivity) {
        // Create node handle referring to the old node so that it is
        // immediately removed from the graph when the node handle is destroyed.
        DSNodeHandle OldNNH = N;
        N->foldNodeCompletely();
        if (DSNode *FN = N->getForwardNode())
          N = FN;
      }
      return N;
    }

    /// setDestTo - Set the ScalarMap entry for the specified value to point to
    /// the specified destination.  If the Value already points to a node, make
    /// sure to merge the two destinations together.
    ///
    void setDestTo(Value &V, const DSNodeHandle &NH);

    /// getValueDest - Return the DSNode that the actual value points to.
    ///
    DSNodeHandle getValueDest(Value &V);

    /// getLink - This method is used to return the specified link in the
    /// specified node if one exists.  If a link does not already exist (it's
    /// null), then we create a new node, link it, then return it.
    ///
    DSNodeHandle &getLink(const DSNodeHandle &Node, unsigned Link = 0);
  };
}

using namespace DS;

//===----------------------------------------------------------------------===//
// DSGraph constructor - Simply use the GraphBuilder to construct the local
// graph.
DSGraph::DSGraph(EquivalenceClasses<GlobalValue*> &ECs, const TargetData &td,
                 Function &F, DSGraph *GG)
  : GlobalsGraph(GG), ScalarMap(ECs), TD(td) {
  PrintAuxCalls = false;

  DEBUG(std::cerr << "  [Loc] Calculating graph for: " << F.getName() << "\n");

  // Use the graph builder to construct the local version of the graph
  GraphBuilder B(F, *this, ReturnNodes[&F], FunctionCalls);
#ifndef NDEBUG
  Timer::addPeakMemoryMeasurement();
#endif

  // If there are any constant globals referenced in this function, merge their
  // initializers into the local graph from the globals graph.
  if (ScalarMap.global_begin() != ScalarMap.global_end()) {
    ReachabilityCloner RC(*this, *GG, 0);

    for (DSScalarMap::global_iterator I = ScalarMap.global_begin();
         I != ScalarMap.global_end(); ++I)
      if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
        if (!GV->isExternal() && GV->isConstant())
          RC.merge(ScalarMap[GV], GG->ScalarMap[GV]);
  }

  markIncompleteNodes(DSGraph::MarkFormalArgs);

  markUnknownNodes();

  // Remove any nodes made dead due to merging...
  removeDeadNodes(DSGraph::KeepUnreachableGlobals);
}


//===----------------------------------------------------------------------===//
// Helper method implementations...
//

static bool getSourcePointerValues(Value* V, std::set<Value*>& sources) {
  std::queue<Value*> tocheck;
  std::set<Value*> visited;
  tocheck.push(V);
  while (!tocheck.empty()) {
    V = tocheck.front();
    tocheck.pop();
    if (visited.find(V) == visited.end()) {
      visited.insert(V);
      if (isa<PointerType>(V->getType())) {
        sources.insert(V);
      } else if (ConstantInt* N = dyn_cast<ConstantInt>(V)) {
        if (!(-N->getSExtValue() <= 124 && -N->getSExtValue() >= 0)) {
          goto fail;
        }
      } else if (PHINode* N = dyn_cast<PHINode>(V)) {
        for (unsigned x = 0; x < N->getNumIncomingValues(); ++x)
          tocheck.push(N->getIncomingValue(x));
      } else if (CastInst* N = dyn_cast<CastInst>(V)) {
        tocheck.push(N->getOperand(0));
      } else if (ConstantExpr* N = dyn_cast<ConstantExpr>(V)) {
        if (N->getOpcode() == Instruction::Cast) {
          tocheck.push(N->getOperand(0));
        } else {
          goto fail;
        }
      } else {
        goto fail;
      }
    }
  }
  ++CastTraceT;
  return true;
 fail:
  ++CastTraceF;
  std::cerr << "Int2Ptr: fail ";
  V->dump();
  return false;
}

/// getValueDest - Return the DSNode that the actual value points to.
///
DSNodeHandle GraphBuilder::getValueDest(Value &Val) {
  Value *V = &Val;
  if (isa<Constant>(V) && cast<Constant>(V)->isNullValue())
    return 0;  // Null doesn't point to anything, don't add to ScalarMap!

  DSNodeHandle &NH = ScalarMap[V];
  if (!NH.isNull())
    return NH;     // Already have a node?  Just return it...

  // Otherwise we need to create a new node to point to.
  // Check first for constant expressions that must be traversed to
  // extract the actual value.
  DSNode* N;
  if (GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
    // Create a new global node for this global variable.
    N = createNode(GV->getType()->getElementType());
    N->addGlobal(GV);
  } else if (Constant *C = dyn_cast<Constant>(V)) {
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
      std::set<Value*> sources;
      if (getSourcePointerValues(CE, sources)) {
        NH = createNode();
        for (std::set<Value*>::iterator ii = sources.begin(), ee = sources.end();
             ii != ee; ++ii)
          NH.mergeWith(getValueDest(**ii));
      } else if (CE->getOpcode() == Instruction::GetElementPtr) {
        visitGetElementPtrInst(*CE);
        DSScalarMap::iterator I = ScalarMap.find(CE);
        assert(I != ScalarMap.end() && "GEP didn't get processed right?");
        NH = I->second;
      } else {
        // This returns a conservative unknown node for any unhandled ConstExpr
        return NH = createNode()->setUnknownNodeMarker();
      }
      if (NH.isNull()) {  // (getelementptr null, X) returns null
        ScalarMap.erase(V);
        return 0;
      }
      return NH;
    } else if (isa<UndefValue>(C)) {
      ScalarMap.erase(V);
      return 0;
    } else {
      assert(0 && "Unknown constant type!");
    }
    N = createNode(); // just create a shadow node
  } else {
    // Otherwise just create a shadow node
    N = createNode();
  }

  NH.setTo(N, 0);      // Remember that we are pointing to it...
  return NH;
}


/// getLink - This method is used to return the specified link in the
/// specified node if one exists.  If a link does not already exist (it's
/// null), then we create a new node, link it, then return it.  We must
/// specify the type of the Node field we are accessing so that we know what
/// type should be linked to if we need to create a new node.
///
DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node, unsigned LinkNo) {
  DSNodeHandle &Node = const_cast<DSNodeHandle&>(node);
  DSNodeHandle &Link = Node.getLink(LinkNo);
  if (Link.isNull()) {
    // If the link hasn't been created yet, make and return a new shadow node
    Link = createNode();
  }
  return Link;
}


/// setDestTo - Set the ScalarMap entry for the specified value to point to the
/// specified destination.  If the Value already points to a node, make sure to
/// merge the two destinations together.
///
void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
  ScalarMap[&V].mergeWith(NH);
}


//===----------------------------------------------------------------------===//
// Specific instruction type handler implementations...
//

/// Alloca & Malloc instruction implementation - Simply create a new memory
/// object, pointing the scalar to it.
///
void GraphBuilder::handleAlloc(AllocationInst &AI, bool isHeap) {
  DSNode *N = createNode();
  if (isHeap)
    N->setHeapNodeMarker();
  else
    N->setAllocaNodeMarker();
  setDestTo(AI, N);
}

// PHINode - Make the scalar for the PHI node point to all of the things the
// incoming values point to... which effectively causes them to be merged.
//
void GraphBuilder::visitPHINode(PHINode &PN) {
  if (!isPointerType(PN.getType())) return; // Only pointer PHIs

  DSNodeHandle PNDest = getValueDest(PN);
  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
    PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
}

void GraphBuilder::visitSelectInst(SelectInst &SI) {
  if (!isPointerType(SI.getType())) return; // Only pointer Selects

  DSNodeHandle Dest = getValueDest(SI);
  Dest.mergeWith(getValueDest(*SI.getOperand(1)));
  Dest.mergeWith(getValueDest(*SI.getOperand(2)));
}

void GraphBuilder::visitSetCondInst(SetCondInst &SCI) {
  if (!isPointerType(SCI.getOperand(0)->getType()) ||
      isa<ConstantPointerNull>(SCI.getOperand(1))) return; // Only pointers
  getValueDest(*SCI.getOperand(0)).mergeWith(getValueDest(*SCI.getOperand(1)));
}


void GraphBuilder::visitGetElementPtrInst(User &GEP) {

#ifdef LLVA_KERNEL
#if 0
  int debug = 0;
  if (isa<Instruction>(GEP)) {
    Instruction * IGEP = (Instruction *)(&GEP);
    if (IGEP->getParent()->getParent()->getName() == "alloc_vfsmnt")
    {
#if 0
      if (G.getPoolDescriptorsMap().count(N) != 0)
        if (G.getPoolDescriptorsMap()[N])
  std::cerr << "LLVA: GEP[" << count << "]: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[N]->getMetaPoolValue()->getName() << "\n";
#else
    debug = 1;
#endif
    }
  }
#endif
#endif

  DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
  if (Value.isNull())
    Value = createNode();

  // As a special case, if all of the index operands of GEP are constant zeros,
  // handle this just like we handle casts (ie, don't do much).
  bool AllZeros = true;
  for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i)
    if (GEP.getOperand(i) !=
           Constant::getNullValue(GEP.getOperand(i)->getType())) {
      AllZeros = false;
      break;
    }

  // If all of the indices are zero, the result points to the operand without
  // applying the type.
  if (AllZeros || (!Value.isNull() &&
                   Value.getNode()->isNodeCompletelyFolded())) {
    setDestTo(GEP, Value);
#if 0
if (debug) std::cerr << "LLVA: GEP: All Zeros\n";
  if (G.getPoolDescriptorsMap()[Value.getNode()])
    std::cerr << "LLVA: GEP: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[Value.getNode()]->getName() << "\n";
#endif
    return;
  }


  const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
  const Type *CurTy = PTy->getElementType();

  if (Value.getNode()->mergeTypeInfo(CurTy, Value.getOffset())) {
    // If the node had to be folded... exit quickly
    setDestTo(GEP, Value);  // GEP result points to folded node

    return;
  }

  const TargetData &TD = Value.getNode()->getTargetData();

#if 0
  // Handle the pointer index specially...
  if (GEP.getNumOperands() > 1 &&
      (!isa<Constant>(GEP.getOperand(1)) ||
       !cast<Constant>(GEP.getOperand(1))->isNullValue())) {

    // If we already know this is an array being accessed, don't do anything...
    if (!TopTypeRec.isArray) {
      TopTypeRec.isArray = true;

      // If we are treating some inner field pointer as an array, fold the node
      // up because we cannot handle it right.  This can come because of
      // something like this:  &((&Pt->X)[1]) == &Pt->Y
      //
      if (Value.getOffset()) {
        // Value is now the pointer we want to GEP to be...
        Value.getNode()->foldNodeCompletely();
        setDestTo(GEP, Value);  // GEP result points to folded node
        return;
      } else {
        // This is a pointer to the first byte of the node.  Make sure that we
        // are pointing to the outter most type in the node.
        // FIXME: We need to check one more case here...
      }
    }
  }
#endif

  // All of these subscripts are indexing INTO the elements we have...
  unsigned Offset = 0;
  for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP);
       I != E; ++I)
    if (const StructType *STy = dyn_cast<StructType>(*I)) {
      const ConstantInt* CUI = cast<ConstantInt>(I.getOperand());
      unsigned FieldNo = 
        CUI->getType()->isSigned() ? CUI->getSExtValue() : CUI->getZExtValue();
      Offset += (unsigned)TD.getStructLayout(STy)->MemberOffsets[FieldNo];
    } else if (isa<PointerType>(*I)) {
      if (!isa<Constant>(I.getOperand()) ||
          !cast<Constant>(I.getOperand())->isNullValue())
        Value.getNode()->setArrayMarker();
    }


#if 0
    if (const SequentialType *STy = cast<SequentialType>(*I)) {
      CurTy = STy->getElementType();
      if (ConstantInt *CS = dyn_cast<ConstantInt>(GEP.getOperand(i))) {
        Offset += 
          (CS->getType()->isSigned() ? CS->getSExtValue() : CS->getZExtValue())
          * TD.getTypeSize(CurTy);
      } else {
        // Variable index into a node.  We must merge all of the elements of the
        // sequential type here.
        if (isa<PointerType>(STy))
          std::cerr << "Pointer indexing not handled yet!\n";
        else {
          const ArrayType *ATy = cast<ArrayType>(STy);
          unsigned ElSize = TD.getTypeSize(CurTy);
          DSNode *N = Value.getNode();
          assert(N && "Value must have a node!");
          unsigned RawOffset = Offset+Value.getOffset();

          // Loop over all of the elements of the array, merging them into the
          // zeroth element.
          for (unsigned i = 1, e = ATy->getNumElements(); i != e; ++i)
            // Merge all of the byte components of this array element
            for (unsigned j = 0; j != ElSize; ++j)
              N->mergeIndexes(RawOffset+j, RawOffset+i*ElSize+j);
        }
      }
    }
#endif

  // Add in the offset calculated...
  Value.setOffset(Value.getOffset()+Offset);

  // Check the offset
  DSNode *N = Value.getNode();
  if (N &&
      !N->isNodeCompletelyFolded() &&
      (N->getSize() != 0 || Offset != 0) &&
      !N->isForwarding()) {
    if ((Offset >= N->getSize()) || int(Offset) < 0) {
      // Accessing offsets out of node size range
      // This is seen in the "magic" struct in named (from bind), where the
      // fourth field is an array of length 0, presumably used to create struct
      // instances of different sizes

      // Collapse the node since its size is now variable
      N->foldNodeCompletely();
    }
  }

  // Value is now the pointer we want to GEP to be...  
  setDestTo(GEP, Value);
#if 0
  if (debug && (isa<Instruction>(GEP))) {
    Instruction * IGEP = (Instruction *)(&GEP);
    DSNode * N = Value.getNode();
    if (IGEP->getParent()->getParent()->getName() == "alloc_vfsmnt")
    {
      if (G.getPoolDescriptorsMap().count(N) != 0)
        if (G.getPoolDescriptorsMap()[N])
  std::cerr << "LLVA: GEP[" << 0 << "]: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[N]->getName() << "\n";
    }
  }
#endif

}

void GraphBuilder::visitLoadInst(LoadInst &LI) {
  DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
  if (Ptr.isNull())
    Ptr = createNode();

  // Make that the node is read from...
  Ptr.getNode()->setReadMarker();

  // Ensure a typerecord exists...
  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);

  if (isPointerType(LI.getType()))
    setDestTo(LI, getLink(Ptr));
#if 0
  if (G.getPoolDescriptorsMap()[getLink(Ptr).getNode()])
    std::cerr << "LLVA: Load: Pool for " << LI.getName() << " is " << G.getPoolDescriptorsMap()[getLink(Ptr).getNode()]->getName() << "\n";
#endif
}

void GraphBuilder::visitStoreInst(StoreInst &SI) {
  const Type *StoredTy = SI.getOperand(0)->getType();
  DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
  if (Dest.isNull()) return;

  // Mark that the node is written to...
  Dest.getNode()->setModifiedMarker();

  // Ensure a type-record exists...
  Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());

  // Avoid adding edges from null, or processing non-"pointer" stores
  if (isPointerType(StoredTy))
    Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
#ifdef LLVA_KERNEL
#if 0
  {
    if (SI.getParent()->getParent()->getName() == "alloc_vfsmnt") {
      DSNode * N = getValueDest(*SI.getOperand(1)).getNode();
      if (N->getMP())
        std::cerr << "LLVA: Store: Pool for " << SI.getName() << " is " << N->getMP() << "\n";
    }
  }
#endif
#endif
}

void GraphBuilder::visitReturnInst(ReturnInst &RI) {
  if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()))
    RetNode->mergeWith(getValueDest(*RI.getOperand(0)));
}

void GraphBuilder::visitVAArgInst(VAArgInst &I) {
  //FIXME: also updates the argument
  DSNodeHandle Ptr = getValueDest(*I.getOperand(0));
  if (Ptr.isNull()) return;

  // Make that the node is read from.
  Ptr.getNode()->setReadMarker();

  // Ensure a type record exists.
  DSNode *PtrN = Ptr.getNode();
  PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset(), false);

  if (isPointerType(I.getType()))
    setDestTo(I, getLink(Ptr));
}


void GraphBuilder::visitCallInst(CallInst &CI) {
  visitCallSite(&CI);
}

void GraphBuilder::visitInvokeInst(InvokeInst &II) {
  visitCallSite(&II);
}

/// returns true if the intrinsic is handled
bool GraphBuilder::visitIntrinsic(CallSite CS, Function *F) {
  switch (F->getIntrinsicID()) {
  case Intrinsic::vastart:
    getValueDest(*CS.getInstruction()).getNode()->setAllocaNodeMarker();
    return true;
  case Intrinsic::vacopy:
    getValueDest(*CS.getInstruction()).
      mergeWith(getValueDest(**(CS.arg_begin())));
    return true;
  case Intrinsic::vaend:
  case Intrinsic::dbg_func_start:
  case Intrinsic::dbg_region_end:
  case Intrinsic::dbg_stoppoint:
    return true;  // noop
  case Intrinsic::memcpy_i32: 
  case Intrinsic::memcpy_i64:
  case Intrinsic::memmove_i32:
  case Intrinsic::memmove_i64: {
    // Merge the first & second arguments, and mark the memory read and
    // modified.
    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
    if (DSNode *N = RetNH.getNode())
      N->setModifiedMarker()->setReadMarker();
    return true;
  }
  case Intrinsic::memset_i32:
  case Intrinsic::memset_i64:
    // Mark the memory modified.
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setModifiedMarker();
    return true;
  default:
    DEBUG(std::cerr << "[dsa:local] Unhandled intrinsic: " << F->getName() << "\n");
    return false;
  }
}

/// returns true if the external is a recognized libc function with a 
/// known (and generated) graph
bool GraphBuilder::visitExternal(CallSite CS, Function *F) {
  if (F->getName() == "calloc"
      || F->getName() == "posix_memalign"
      || F->getName() == "memalign" || F->getName() == "valloc") {
    setDestTo(*CS.getInstruction(),
              createNode()->setHeapNodeMarker()->setModifiedMarker());
    return true;
  } else if (F->getName() == "realloc") {
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    if (CS.arg_begin() != CS.arg_end())
      RetNH.mergeWith(getValueDest(**CS.arg_begin()));
    if (DSNode *N = RetNH.getNode())
      N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
    return true;
  } else if (F->getName() == "memmove") {
    // Merge the first & second arguments, and mark the memory read and
    // modified.
    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
    if (DSNode *N = RetNH.getNode())
      N->setModifiedMarker()->setReadMarker();
    return true;
  } else if (F->getName() == "free") {
    // Mark that the node is written to...
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setModifiedMarker()->setHeapNodeMarker();
  } else if (F->getName() == "atoi" || F->getName() == "atof" ||
             F->getName() == "atol" || F->getName() == "atoll" ||
             F->getName() == "remove" || F->getName() == "unlink" ||
             F->getName() == "rename" || F->getName() == "memcmp" ||
             F->getName() == "strcmp" || F->getName() == "strncmp" ||
             F->getName() == "execl" || F->getName() == "execlp" ||
             F->getName() == "execle" || F->getName() == "execv" ||
             F->getName() == "execvp" || F->getName() == "chmod" ||
             F->getName() == "puts" || F->getName() == "write" ||
             F->getName() == "open" || F->getName() == "create" ||
             F->getName() == "truncate" || F->getName() == "chdir" ||
             F->getName() == "mkdir" || F->getName() == "rmdir" ||
             F->getName() == "strlen") {
    // These functions read all of their pointer operands.
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI) {
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();
    }
    return true;
  } else if (F->getName() == "memchr") {
    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
    DSNodeHandle Result = getValueDest(*CS.getInstruction());
    RetNH.mergeWith(Result);
    if (DSNode *N = RetNH.getNode())
      N->setReadMarker();
    return true;
  } else if (F->getName() == "read" || F->getName() == "pipe" ||
             F->getName() == "wait" || F->getName() == "time" ||
             F->getName() == "getrusage") {
    // These functions write all of their pointer operands.
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI) {
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setModifiedMarker();
    }
    return true;
  } else if (F->getName() == "stat" || F->getName() == "fstat" ||
             F->getName() == "lstat") {
    // These functions read their first operand if its a pointer.
    CallSite::arg_iterator AI = CS.arg_begin();
    if (isPointerType((*AI)->getType())) {
      DSNodeHandle Path = getValueDest(**AI);
      if (DSNode *N = Path.getNode()) N->setReadMarker();
    }
    
    // Then they write into the stat buffer.
    DSNodeHandle StatBuf = getValueDest(**++AI);
    if (DSNode *N = StatBuf.getNode()) {
      N->setModifiedMarker();
      const Type *StatTy = F->getFunctionType()->getParamType(1);
      if (const PointerType *PTy = dyn_cast<PointerType>(StatTy))
        N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
    }
    return true;
  } else if (F->getName() == "strtod" || F->getName() == "strtof" ||
             F->getName() == "strtold") {
    // These functions read the first pointer
    if (DSNode *Str = getValueDest(**CS.arg_begin()).getNode()) {
      Str->setReadMarker();
      // If the second parameter is passed, it will point to the first
      // argument node.
      const DSNodeHandle &EndPtrNH = getValueDest(**(CS.arg_begin()+1));
      if (DSNode *End = EndPtrNH.getNode()) {
        End->mergeTypeInfo(PointerType::get(Type::SByteTy),
                           EndPtrNH.getOffset(), false);
        End->setModifiedMarker();
        DSNodeHandle &Link = getLink(EndPtrNH);
        Link.mergeWith(getValueDest(**CS.arg_begin()));
      }
    }
    return true;
  } else if (F->getName() == "fopen" || F->getName() == "fdopen" ||
             F->getName() == "freopen") {
    // These functions read all of their pointer operands.
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI)
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();

    // fopen allocates in an unknown way and writes to the file
    // descriptor.  Also, merge the allocated type into the node.
    DSNodeHandle Result = getValueDest(*CS.getInstruction());
    if (DSNode *N = Result.getNode()) {
      N->setModifiedMarker()->setUnknownNodeMarker();
      const Type *RetTy = F->getFunctionType()->getReturnType();
      if (const PointerType *PTy = dyn_cast<PointerType>(RetTy))
              N->mergeTypeInfo(PTy->getElementType(), Result.getOffset());
    }
    
    // If this is freopen, merge the file descriptor passed in with the
    // result.
    if (F->getName() == "freopen") {
      // ICC doesn't handle getting the iterator, decrementing and
      // dereferencing it in one operation without error. Do it in 2 steps
      CallSite::arg_iterator compit = CS.arg_end();
      Result.mergeWith(getValueDest(**--compit));
    }
    return true;
  } else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){
    // fclose reads and deallocates the memory in an unknown way for the
    // file descriptor.  It merges the FILE type into the descriptor.
    DSNodeHandle H = getValueDest(**CS.arg_begin());
    if (DSNode *N = H.getNode()) {
      N->setReadMarker()->setUnknownNodeMarker();
      const Type *ArgTy = F->getFunctionType()->getParamType(0);
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    return true;
  } else if (CS.arg_end()-CS.arg_begin() == 1 &&
             (F->getName() == "fflush" || F->getName() == "feof" ||
              F->getName() == "fileno" || F->getName() == "clearerr" ||
              F->getName() == "rewind" || F->getName() == "ftell" ||
              F->getName() == "ferror" || F->getName() == "fgetc" ||
              F->getName() == "fgetc" || F->getName() == "_IO_getc")) {
    // fflush reads and writes the memory for the file descriptor.  It
    // merges the FILE type into the descriptor.
    DSNodeHandle H = getValueDest(**CS.arg_begin());
    if (DSNode *N = H.getNode()) {
      N->setReadMarker()->setModifiedMarker();
      
      const Type *ArgTy = F->getFunctionType()->getParamType(0);
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    return true;
  } else if (CS.arg_end()-CS.arg_begin() == 4 &&
             (F->getName() == "fwrite" || F->getName() == "fread")) {
    // fread writes the first operand, fwrite reads it.  They both
    // read/write the FILE descriptor, and merges the FILE type.
    CallSite::arg_iterator compit = CS.arg_end();
    DSNodeHandle H = getValueDest(**--compit);
    if (DSNode *N = H.getNode()) {
      N->setReadMarker()->setModifiedMarker();
      const Type *ArgTy = F->getFunctionType()->getParamType(3);
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    
    H = getValueDest(**CS.arg_begin());
    if (DSNode *N = H.getNode())
      if (F->getName() == "fwrite")
        N->setReadMarker();
      else
        N->setModifiedMarker();
    return true;
  } else if (F->getName() == "fgets" && CS.arg_end()-CS.arg_begin() == 3){
    // fgets reads and writes the memory for the file descriptor.  It
    // merges the FILE type into the descriptor, and writes to the
    // argument.  It returns the argument as well.
    CallSite::arg_iterator AI = CS.arg_begin();
    DSNodeHandle H = getValueDest(**AI);
    if (DSNode *N = H.getNode())
      N->setModifiedMarker();                        // Writes buffer
    H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
    ++AI; ++AI;
    
    // Reads and writes file descriptor, merge in FILE type.
    H = getValueDest(**AI);
    if (DSNode *N = H.getNode()) {
      N->setReadMarker()->setModifiedMarker();
      const Type *ArgTy = F->getFunctionType()->getParamType(2);
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    return true;
  } else if (F->getName() == "ungetc" || F->getName() == "fputc" ||
             F->getName() == "fputs" || F->getName() == "putc" ||
             F->getName() == "ftell" || F->getName() == "rewind" ||
             F->getName() == "_IO_putc") {
    // These functions read and write the memory for the file descriptor,
    // which is passes as the last argument.
    CallSite::arg_iterator compit = CS.arg_end();
    DSNodeHandle H = getValueDest(**--compit);
    if (DSNode *N = H.getNode()) {
      N->setReadMarker()->setModifiedMarker();
      FunctionType::param_iterator compit2 = F->getFunctionType()->param_end();
      const Type *ArgTy = *--compit2;
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    
    // Any pointer arguments are read.
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI)
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();
    return true;
  } else if (F->getName() == "fseek" || F->getName() == "fgetpos" ||
             F->getName() == "fsetpos") {
    // These functions read and write the memory for the file descriptor,
    // and read/write all other arguments.
    DSNodeHandle H = getValueDest(**CS.arg_begin());
    if (DSNode *N = H.getNode()) {
      FunctionType::param_iterator compit2 = F->getFunctionType()->param_end();
      const Type *ArgTy = *--compit2;
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    
    // Any pointer arguments are read.
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI)
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker()->setModifiedMarker();
    return true;
  } else if (F->getName() == "printf" || F->getName() == "fprintf" ||
             F->getName() == "sprintf") {
    CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
    
    if (F->getName() == "fprintf") {
      // fprintf reads and writes the FILE argument, and applies the type
      // to it.
      DSNodeHandle H = getValueDest(**AI);
      if (DSNode *N = H.getNode()) {
        N->setModifiedMarker();
        const Type *ArgTy = (*AI)->getType();
        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
      }
    } else if (F->getName() == "sprintf") {
      // sprintf writes the first string argument.
      DSNodeHandle H = getValueDest(**AI++);
      if (DSNode *N = H.getNode()) {
        N->setModifiedMarker();
        const Type *ArgTy = (*AI)->getType();
        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
      }
    }
    
    for (; AI != E; ++AI) {
      // printf reads all pointer arguments.
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();
    }
    return true;
  } else if (F->getName() == "vprintf" || F->getName() == "vfprintf" ||
             F->getName() == "vsprintf") {
    CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
    
    if (F->getName() == "vfprintf") {
      // ffprintf reads and writes the FILE argument, and applies the type
      // to it.
      DSNodeHandle H = getValueDest(**AI);
      if (DSNode *N = H.getNode()) {
        N->setModifiedMarker()->setReadMarker();
        const Type *ArgTy = (*AI)->getType();
        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
      }
      ++AI;
    } else if (F->getName() == "vsprintf") {
      // vsprintf writes the first string argument.
      DSNodeHandle H = getValueDest(**AI++);
      if (DSNode *N = H.getNode()) {
        N->setModifiedMarker();
        const Type *ArgTy = (*AI)->getType();
        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
      }
    }
    
    // Read the format
    if (AI != E) {
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();
      ++AI;
    }
    
    // Read the valist, and the pointed-to objects.
    if (AI != E && isPointerType((*AI)->getType())) {
      const DSNodeHandle &VAList = getValueDest(**AI);
      if (DSNode *N = VAList.getNode()) {
        N->setReadMarker();
        N->mergeTypeInfo(PointerType::get(Type::SByteTy),
        		 VAList.getOffset(), false);
	
        DSNodeHandle &VAListObjs = getLink(VAList);
        VAListObjs.getNode()->setReadMarker();
      }
    }
    
    return true;
  } else if (F->getName() == "scanf" || F->getName() == "fscanf" ||
             F->getName() == "sscanf") {
    CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
    
    if (F->getName() == "fscanf") {
      // fscanf reads and writes the FILE argument, and applies the type
      // to it.
      DSNodeHandle H = getValueDest(**AI);
      if (DSNode *N = H.getNode()) {
        N->setReadMarker();
        const Type *ArgTy = (*AI)->getType();
        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
      }
    } else if (F->getName() == "sscanf") {
      // sscanf reads the first string argument.
      DSNodeHandle H = getValueDest(**AI++);
      if (DSNode *N = H.getNode()) {
        N->setReadMarker();
        const Type *ArgTy = (*AI)->getType();
        if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
          N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
      }
    }
    
    for (; AI != E; ++AI) {
      // scanf writes all pointer arguments.
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setModifiedMarker();
    }
    return true;
  } else if (F->getName() == "strtok") {
    // strtok reads and writes the first argument, returning it.  It reads
    // its second arg.  FIXME: strtok also modifies some hidden static
    // data.  Someday this might matter.
    CallSite::arg_iterator AI = CS.arg_begin();
    DSNodeHandle H = getValueDest(**AI++);
    if (DSNode *N = H.getNode()) {
      N->setReadMarker()->setModifiedMarker();      // Reads/Writes buffer
      const Type *ArgTy = F->getFunctionType()->getParamType(0);
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
    
    H = getValueDest(**AI);       // Reads delimiter
    if (DSNode *N = H.getNode()) {
      N->setReadMarker();
      const Type *ArgTy = F->getFunctionType()->getParamType(1);
      if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
        N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
    }
    return true;
  } else if (F->getName() == "strchr" || F->getName() == "strrchr" ||
             F->getName() == "strstr") {
    // These read their arguments, and return the first one
    DSNodeHandle H = getValueDest(**CS.arg_begin());
    H.mergeWith(getValueDest(*CS.getInstruction())); // Returns buffer
    
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI)
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();
    
    if (DSNode *N = H.getNode())
      N->setReadMarker();
    return true;
  } else if (F->getName() == "__assert_fail") {
    for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
         AI != E; ++AI)
      if (isPointerType((*AI)->getType()))
        if (DSNode *N = getValueDest(**AI).getNode())
          N->setReadMarker();
    return true;
  } else if (F->getName() == "modf" && CS.arg_end()-CS.arg_begin() == 2) {
    // This writes its second argument, and forces it to double.
    CallSite::arg_iterator compit = CS.arg_end();
    DSNodeHandle H = getValueDest(**--compit);
    if (DSNode *N = H.getNode()) {
      N->setModifiedMarker();
      N->mergeTypeInfo(Type::DoubleTy, H.getOffset());
    }
    return true;
  } else if (F->getName() == "strcat" || F->getName() == "strncat") {
    //This might be making unsafe assumptions about usage
    //Merge return and first arg
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    RetNH.mergeWith(getValueDest(**CS.arg_begin()));
    if (DSNode *N = RetNH.getNode())
      N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
    //and read second pointer
    if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
      N->setReadMarker();
    return true;
  } else if (F->getName() == "strcpy" || F->getName() == "strncpy") {
    //This might be making unsafe assumptions about usage
    //Merge return and first arg
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    RetNH.mergeWith(getValueDest(**CS.arg_begin()));
    if (DSNode *N = RetNH.getNode())
      N->setHeapNodeMarker()->setModifiedMarker();
    //and read second pointer
    if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
            N->setReadMarker();
    return true;
#ifdef LLVA_KERNEL
  } else if (F->getName() == "llva_print_icontext") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_ipush_function0" ||
             F->getName() == "llva_ipush_function1" ||
             F->getName() == "llva_ipush_function3" ||
             F->getName() == "llva_push_function1") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    DSNodeHandle FP = getValueDest(**(CS.arg_begin() + 1));
    RetNH.getNode()->setModifiedMarker()->setReadMarker()->foldNodeCompletely();
    RetNH.addEdgeTo(FP);
    return true;
  } else if (F->getName() == "llva_push_syscall" ) {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin() + 1));
    DSNodeHandle FP = getValueDest(**(CS.arg_begin() + 2));
    RetNH.getNode()->setModifiedMarker()->setReadMarker()->foldNodeCompletely();
    RetNH.addEdgeTo(FP);
    return true;
  } else if (F->getName() == "llva_config_ldt" ||
             F->getName() == "llva_mm_flush_tlb" ||
             F->getName() == "llva_register_syscall_cleaner") {
    return true;
  } else if (F->getName() == "llva_iset_privileged") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_load_invoke") {
    Value* GV = F->getParent()->getNamedGlobal("llva.invoke");
    DSNodeHandle Dest = getValueDest(*GV);
    Dest.getNode()->setModifiedMarker();
    Dest.getNode()->mergeTypeInfo((*CS.arg_begin())->getType(), Dest.getOffset());
    Dest.addEdgeTo(getValueDest(**CS.arg_begin()));
    return true;
  } else if (F->getName() == "llva_save_invoke") {
    Value* GV = F->getParent()->getNamedGlobal("llva.invoke");
    DSNodeHandle Ptr = getValueDest(*GV);
    if (Ptr.isNull())
      Ptr = createNode();
    Ptr.getNode()->setReadMarker();
    Ptr.getNode()->mergeTypeInfo(CS.getInstruction()->getType(), Ptr.getOffset(), false);
    setDestTo(*CS.getInstruction(), getLink(Ptr));
    return true;
  } else if (F->getName() == "llva_mm_load_pgtable") {
      Value* GV = F->getParent()->getNamedGlobal("llva.pgtable");
      DSNodeHandle Dest = getValueDest(*GV);
      Dest.getNode()->setModifiedMarker();
      Dest.getNode()->mergeTypeInfo((*CS.arg_begin())->getType(), Dest.getOffset());
      Dest.addEdgeTo(getValueDest(**CS.arg_begin()));
      return true;
  } else if (F->getName() == "llva_mm_save_pgtable") {
    Value* GV = F->getParent()->getNamedGlobal("llva.pgtable");
    DSNodeHandle Ptr = getValueDest(*GV);
    if (Ptr.isNull())
      Ptr = createNode();
    Ptr.getNode()->setReadMarker();
    Ptr.getNode()->mergeTypeInfo(CS.getInstruction()->getType(), Ptr.getOffset(), false);
    setDestTo(*CS.getInstruction(), getLink(Ptr));
    return true;
  } else if (F->getName() == "llva_load_kstackp") {
      Value* GV = F->getParent()->getNamedGlobal("llva.kstackp");
      DSNodeHandle Dest = getValueDest(*GV);
      Dest.getNode()->setModifiedMarker();
      Dest.getNode()->mergeTypeInfo((*CS.arg_begin())->getType(), Dest.getOffset());
      Dest.addEdgeTo(getValueDest(**CS.arg_begin()));
      return true;
  } else if (F->getName() == "llva_save_kstackp") {
    Value* GV = F->getParent()->getNamedGlobal("llva.kstackp");
    DSNodeHandle Ptr = getValueDest(*GV);
    if (Ptr.isNull())
      Ptr = createNode();
    Ptr.getNode()->setReadMarker();
    Ptr.getNode()->mergeTypeInfo(CS.getInstruction()->getType(), Ptr.getOffset(), false);
    setDestTo(*CS.getInstruction(), getLink(Ptr));
    return true;
  } else if (F->getName() == "llva_icontext_save_retvalue") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_icontext_load_retvalue" ||
             F->getName() == "llva_icontext_lif") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_invokestrnlen") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_unwind") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_set_integer_stackp") {
    DSNodeHandle RetNH = getValueDest(**(CS.arg_begin()));
    RetNH.getNode()->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_strcpy" ||
             F->getName() == "llva_strncpy" ||
             F->getName() == "llva_invokestrncpy") {
    //This might be making unsafe assumptions about usage
    //Merge return and first arg
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    RetNH.mergeWith(getValueDest(**CS.arg_begin()));
    if (DSNode *N = RetNH.getNode())
      N->setHeapNodeMarker()->setModifiedMarker();
    //and read second pointer
    if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
            N->setReadMarker();
    return true;
  } else if (F->getName() == "pchk_drop_slab" ||
             F->getName() == "pchk_drop_obj" ||
             F->getName() == "pchk_drop_pool" ||
             F->getName() == "pchk_reg_obj" ||
             F->getName() == "pchk_reg_slab" ||
             F->getName() == "llva_assert_match_sig") {
    return true;
  } else if (F->getName() == "llva_save_fp" ||
             F->getName() == "llva_save_integer") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    Ptr.getNode()->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_load_fp" ||
             F->getName() == "llva_load_integer" ||
             F->getName() == "llva_get_eip") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    Ptr.getNode()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_save_icontext") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    Ptr.getNode()->setReadMarker();
    Ptr = getValueDest(**(CS.arg_begin() + 1));
    Ptr.getNode()->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_load_icontext") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    Ptr.getNode()->setModifiedMarker();
    Ptr = getValueDest(**(CS.arg_begin() + 1));
    Ptr.getNode()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_register_syscall" ||
             F->getName() == "llva_register_interrupt" ||
             F->getName() == "llva_register_general_exception" ||
             F->getName() == "llva_register_memory_exception") {
    //FIXME: track functions and clear Incomplete flags on them
    //       or set userspace flag on pointers
    return true;
  } else if (F->getName() == "llva_readiob" ||
             F->getName() == "llva_readioh" ||
             F->getName() == "llva_readiow") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    if (Ptr.isNull()) Ptr = createNode();
    Ptr.getNode()->setReadMarker();
    Type* T = 0;
    if (F->getName() == "llva_readiob") T = Type::SByteTy;
    if (F->getName() == "llva_readioh") T = Type::ShortTy;
    if (F->getName() == "llva_readiow") T = Type::IntTy;
    Ptr.getNode()->mergeTypeInfo(T, Ptr.getOffset(), false);
    return true;
  } else if (F->getName() == "llva_writeiob" ||
             F->getName() == "llva_writeioh" ||
             F->getName() == "llva_writeiow") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    if (Ptr.isNull()) Ptr = createNode();
    Ptr.getNode()->setModifiedMarker();
    Type* T = 0;
    if (F->getName() == "llva_writeiob") T = Type::SByteTy;
    if (F->getName() == "llva_writeioh") T = Type::ShortTy;
    if (F->getName() == "llva_writeiow") T = Type::IntTy;
    Ptr.getNode()->mergeTypeInfo(T, Ptr.getOffset(), false);
    return true;
  } else if (F->getName() == "llva_atomic_compare_and_swap" ||
             F->getName() == "llva_atomic_compare_and_swap_p" ||
             F->getName() == "llva_atomic_cas_lw" ||
             F->getName() == "llva_atomic_cas_h" ||
             F->getName() == "llva_atomic_cas_b" ||
             F->getName() == "llva_atomic_fetch_add_store" ||
             F->getName() == "llva_atomic_and" ||
             F->getName() == "llva_atomic_or") {
    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
    if (Ptr.isNull()) Ptr = createNode();
    Ptr.getNode()->setReadMarker();
    Type* T = Type::IntTy;
    if (F->getName() == "llva_atomic_cas_b") T = Type::SByteTy;
    if (F->getName() == "llva_atomic_cas_h") T = Type::ShortTy;
    Ptr.getNode()->mergeTypeInfo(T, Ptr.getOffset(), false);
    return true;
  } else if (F->getName() == "llva_save_tsc" || F->getName() == "llva_load_tsc") {
    return true;
  } else if (F->getName() == "llva_ialloca") {
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    RetNH.mergeWith(getValueDest(**CS.arg_begin()));
    RetNH.getNode()->setModifiedMarker()->setReadMarker()->foldNodeCompletely();
    return true;
  } else if (F->getName() == "llva_ipop_function0") {
    // Mark the memory modified.
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setModifiedMarker()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_init_icontext") {
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    RetNH.mergeWith(getValueDest(**(CS.arg_begin() + 1)));
    RetNH.getNode()->setModifiedMarker()->foldNodeCompletely();
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setReadMarker();
    return true;
  } else if (F->getName() == "llva_was_privileged") {
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setReadMarker();
    return true;
  } else if (F->getName() == "llva_clear_icontext") {
    // Mark the memory modified.
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_memset" ||
             F->getName() == "llva_invokememset") {
    // Mark the memory modified.
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setModifiedMarker();
    return true;
  } else if (F->getName() == "llva_memcpy") {
    // Merge the first & second arguments, and mark the memory read and
    // modified.
    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
    if (DSNode *N = RetNH.getNode())
      N->setModifiedMarker()->setReadMarker();
    return true;
  } else if (F->getName() == "llva_invokememcpy") {
    //Find types
    const Type* T1 = CS.getInstruction()->getOperand(1)->getType();
    const Type* T2 = CS.getInstruction()->getOperand(2)->getType();
    if (CastInst* CI1 = dyn_cast<CastInst>(CS.getInstruction()->getOperand(1)))
      T1 = CI1->getOperand(0)->getType();
    if (CastInst* CI2 = dyn_cast<CastInst>(CS.getInstruction()->getOperand(2)))
      T2 = CI2->getOperand(0)->getType();
    if (const PointerType* P1 = dyn_cast<PointerType>(T1))
      T1 = P1->getElementType();
    if (const PointerType* P2 = dyn_cast<PointerType>(T2))
      T2 = P2->getElementType();

    uint64_t len = 0;
    if (ConstantInt* CI = dyn_cast<ConstantInt>(CS.getInstruction()->getOperand(3)))
      len = CI->getZExtValue();

    DSNodeHandle NH1 = getValueDest(**CS.arg_begin());
    DSNodeHandle NH2 = getValueDest(**(CS.arg_begin()+1));

    const TargetData &TD = NH1.getNode()->getTargetData();
    const Type* TTU = T1;
    bool isArray = false;
    if (isa<StructType>(T1) && TD.getTypeSize(T1) >= TD.getTypeSize(T2))
      TTU = T1;
    else if (isa<StructType>(T2))
      TTU = T2;
    else
      isArray = true;

    if (TD.getTypeSize(TTU) < len)
      isArray = true;

    if (NH1.getNode()->getType() == Type::VoidTy)
      NH1.getNode()->mergeTypeInfo(TTU, NH1.getOffset(), false);
    if (NH2.getNode()->getType() == Type::VoidTy)
      NH2.getNode()->mergeTypeInfo(TTU, NH2.getOffset(), false);
    
    if (isArray) {
      NH1.getNode()->setArrayMarker();
      NH2.getNode()->setArrayMarker();
    }

    NH1.getNode()->mergeTypeInfo(TTU, NH1.getOffset(), false);
    NH2.getNode()->mergeTypeInfo(TTU, NH2.getOffset(), false);
    
    NH1.getNode()->setModifiedMarker();
    NH2.getNode()->setReadMarker();

    for (unsigned i = 0; i < len / 4; ++i) {
      int x = NH1.getNode()->isArray() ? 0 : (NH1.getOffset() / 4 + i);
      int y = NH2.getNode()->isArray() ? 0 : (NH2.getOffset() / 4 + i);
      NH1.getNode()->getLink(x*4).mergeWith(NH2.getNode()->getLink(y*4));
    }
#if 0
    // Merge the first & second arguments, and mark the memory read and
    // modified.
    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
    if (DSNode *N = RetNH.getNode())
      N->setModifiedMarker()->setReadMarker();
#endif
    return true;
  } else if (F->getName() == "llva_save_stackp" ||
             F->getName() == "llvm.returnaddress") {
      // Create a new DSNode for the memory returned by llva_save_stackp()
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    RetNH.getNode()->setAllocaNodeMarker();
    RetNH.getNode()->setUnknownNodeMarker();
    RetNH.getNode()->foldNodeCompletely();
    return true;
  } else if (F->getName() == "llva_get_icontext_stackp") {
    // Create a new DSNode for the memory returned by llva_save_stackp()
    DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
    //    RetNH.getNode()->setAllocaNodeMarker();
    //    RetNH.getNode()->setUnknownNodeMarker();
    //    RetNH.getNode()->foldNodeCompletely();
    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
      N->setReadMarker();
    return true;
  } else if (F->getName() == "llva_set_icontext_stackp") {
    DSNodeHandle Dest = getValueDest(**CS.arg_begin());
    // Mark that the node is written to...
    Dest.getNode()->setModifiedMarker();
    Dest.getNode()->foldNodeCompletely();
    getLink(Dest).mergeWith(getValueDest(**(CS.arg_begin() + 1)));
    return true;

#if 0
  } else if (F->getName() == "__generic_copy_from_user") {
    if (CS.getCaller()->getName() == "kmem_cache_alloc")
        return false;
    // Merge the first & second arguments, and mark the memory read and
    // modified.
    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
    if (DSNode *N = RetNH.getNode())
      N->setModifiedMarker()->setReadMarker();
    return true;
#endif
#endif
  }

  return false;
}

void GraphBuilder::visitCallSite(CallSite CS) {
  Value *Callee = CS.getCalledValue();
  bool isSyscall6 = false;

  if (Function *F = dyn_cast<Function>(Callee)) {
    // Determine if the called function is one of the specified heap
    // allocation functions
    if (AllocList.end() != std::find(AllocList.begin(), AllocList.end(), F->getName())) {
      DSNodeHandle RetNH;
      RetNH = getValueDest(*CS.getInstruction());
      RetNH.getNode()->setHeapNodeMarker()->setModifiedMarker();
      RetNH.getNode()->getMP()->addCallSite(CS);

      //
      // Anything that is not a pool allocator must mark objects as
      // type-unknown.
      //
      if (F->getName() != "kmem_cache_alloc")
        RetNH.getNode()->foldNodeCompletely();
      return;
    }

#ifdef SVA_IO
    //
    // Determine whether this is a call to a function that allocates an I/O
    // object.  If so, then make it with the I/O flags and make it
    // type-unknown (as the I/O device may treat the memory as a type different
    // than what we infer).
    //
    if (IOAllocList.end() != std::find(IOAllocList.begin(), IOAllocList.end(), F->getName())) {
      DSNodeHandle RetNH;
      if (F->getName() == "pseudo_alloc")
        RetNH = getValueDest(**CS.arg_begin());
      else
        RetNH = getValueDest(*CS.getInstruction());
      RetNH.getNode()->setIONodeMarker()->setModifiedMarker();
      RetNH.getNode()->getMP()->addCallSite(CS);
      RetNH.getNode()->foldNodeCompletely();
      return;
    }
#endif

    // Determine if the called function is one of the specified heap
    // free functions
    if (FreeList.end() != std::find(FreeList.begin(), FreeList.end(),
                                    F->getName())) {
      // Mark that the node is written to...
      if (DSNode *N = getValueDest(*(CS.getArgument(0))).getNode())
        N->setModifiedMarker()->setHeapNodeMarker();
      return;
    }

    if (F->getName() == "llva_syscall6") 
      isSyscall6 = true;

    if (F->isExternal()) {
      if (F->isIntrinsic() && visitIntrinsic(CS, F))
        return;
      
      if (visitExternal(CS,F))
        return;

      if (!isSyscall6) {
        // Unknown function, warn if it returns a pointer type or takes a
        // pointer argument.
        bool Warn = isPointerType(CS.getInstruction()->getType());
        if (!Warn)
          for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
               I != E; ++I)
            if (isPointerType((*I)->getType())) {
              Warn = true;
              break;
            }
        if (Warn) {
          std::cerr << "WARNING: Call to unknown external function '"
                    << F->getName() << "' will cause pessimistic results!\n";
        }
      }
    }
  }

#ifdef LLVA_KERNEL
  if (isSyscall6) {
    assert (isa<ConstantInt>(CS.getArgument(0)) && "llva_syscall6 called with non-const argument");
    ConstantInt * C = dyn_cast<ConstantInt>(CS.getArgument(0));
    Callee = syscalls[C->getSExtValue()];
    assert (Callee && "llva_syscall: No target for system call vector");
  }
#endif

  // Set up the return value...
  DSNodeHandle RetVal;
  Instruction *I = CS.getInstruction();
  if (isPointerType(I->getType()))
    RetVal = getValueDest(*I);

  DSNode *CalleeNode = 0;
  if (DisableDirectCallOpt || !isa<Function>(Callee)) {
    CalleeNode = getValueDest(*Callee).getNode();
    if (CalleeNode == 0) {
      std::cerr << "WARNING: Program is calling through a null pointer?\n"<< *I;
      return;  // Calling a null pointer?
    }
  }

  std::vector<DSNodeHandle> Args;
  Args.reserve(CS.arg_end()-CS.arg_begin());
    
  // Calculate the arguments vector...
  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
    if (isPointerType((*I)->getType()))
      Args.push_back(getValueDest(**I));

  // Add a new function call entry...
  if (CalleeNode)
    FunctionCalls->push_back(DSCallSite(CS, RetVal, CalleeNode, Args));
  else
    FunctionCalls->push_back(DSCallSite(CS, RetVal, cast<Function>(Callee),
                                        Args));
}

void GraphBuilder::visitFreeInst(FreeInst &FI) {
  // Mark that the node is written to...
  if (DSNode *N = getValueDest(*FI.getOperand(0)).getNode())
    N->setModifiedMarker()->setHeapNodeMarker();
}

/// Handle casts...
void GraphBuilder::visitCastInst(CastInst &CI) {
  if (isPointerType(CI.getType()))
    if (isPointerType(CI.getOperand(0)->getType())) {
      DSNodeHandle Ptr = getValueDest(*CI.getOperand(0));
      if (Ptr.getNode() == 0) return;

      // Cast one pointer to the other, just act like a copy instruction
      setDestTo(CI, Ptr);
    } else {
      // Cast something (floating point, small integer) to a pointer.  We need
      // to track the fact that the node points to SOMETHING, just something we
      // don't know about.  Make an "Unknown" node.
      //

      //Try to track all values of ints back to constants or valid pointers
      std::set<Value*> sources;
      if (getSourcePointerValues(CI.getOperand(0), sources)) {
        setDestTo(CI, createNode());
        for (std::set<Value*>::iterator ii = sources.begin(), ee = sources.end();
             ii != ee; ++ii)
          getValueDest(CI).mergeWith(getValueDest(**ii));
      } else {
        if (DebugUnknown) {
          std::cerr << "In " << CI.getParent()->getParent()->getName() << " ";
          CI.dump();
        }
        setDestTo(CI, createNode()->setUnknownNodeMarker());
      } 
    }
}


// visitInstruction - For all other instruction types, if we have any arguments
// that are of pointer type, make them have unknown composition bits, and merge
// the nodes together.
void GraphBuilder::visitInstruction(Instruction &Inst) {
  DSNodeHandle CurNode;
  if (isPointerType(Inst.getType()))
    CurNode = getValueDest(Inst);
  for (User::op_iterator I = Inst.op_begin(), E = Inst.op_end(); I != E; ++I)
    if (isPointerType((*I)->getType()))
      CurNode.mergeWith(getValueDest(**I));

  if (DSNode *N = CurNode.getNode()) {
    if (DebugUnknown) {
      std::cerr << "In " << Inst.getParent()->getParent()->getName() << " ";
      Inst.dump();
    }
    N->setUnknownNodeMarker();
  }
}



//===----------------------------------------------------------------------===//
// LocalDataStructures Implementation
//===----------------------------------------------------------------------===//

// MergeConstantInitIntoNode - Merge the specified constant into the node
// pointed to by NH.
void GraphBuilder::MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C) {
  // Ensure a type-record exists...
  DSNode *NHN = NH.getNode();
  NHN->mergeTypeInfo(C->getType(), NH.getOffset());

  if (C->getType()->isFirstClassType()) {
    if (isPointerType(C->getType()))
      // Avoid adding edges from null, or processing non-"pointer" stores
      NH.addEdgeTo(getValueDest(*C));
    return;
  }

  const TargetData &TD = NH.getNode()->getTargetData();

  if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
      // We don't currently do any indexing for arrays...
      MergeConstantInitIntoNode(NH, cast<Constant>(CA->getOperand(i)));
  } else if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
    const StructLayout *SL = TD.getStructLayout(CS->getType());
    for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
      DSNode *NHN = NH.getNode();
      //Some programmers think ending a structure with a [0 x sbyte] is cute
      if (SL->MemberOffsets[i] < SL->StructSize) {
        DSNodeHandle NewNH(NHN, NH.getOffset()+(unsigned)SL->MemberOffsets[i]);
        MergeConstantInitIntoNode(NewNH, cast<Constant>(CS->getOperand(i)));
      } else if (SL->MemberOffsets[i] == SL->StructSize) {
        DEBUG(std::cerr << "Zero size element at end of struct\n");
        NHN->foldNodeCompletely();
      } else {
        assert(0 && "type was smaller than offsets of of struct layout indicate");
      }
    }
  } else if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) {
    // Noop
  } else {
    assert(0 && "Unknown constant type!");
  }
}

void GraphBuilder::mergeInGlobalInitializer(GlobalVariable *GV) {
  assert(!GV->isExternal() && "Cannot merge in external global!");
  // Get a node handle to the global node and merge the initializer into it.
  DSNodeHandle NH = getValueDest(*GV);
  MergeConstantInitIntoNode(NH, GV->getInitializer());
  NH.getNode()->getMP()->addGlobal(GV);
}


/// BuildGlobalECs - Look at all of the nodes in the globals graph.  If any node
/// contains multiple globals, DSA will never, ever, be able to tell the globals
/// apart.  Instead of maintaining this information in all of the graphs
/// throughout the entire program, store only a single global (the "leader") in
/// the graphs, and build equivalence classes for the rest of the globals.
static void BuildGlobalECs(DSGraph &GG, std::set<GlobalValue*> &ECGlobals) {
  DSScalarMap &SM = GG.getScalarMap();
  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
  for (DSGraph::node_iterator I = GG.node_begin(), E = GG.node_end();
       I != E; ++I) {
    if (I->getGlobalsList().size() <= 1) continue;

    // First, build up the equivalence set for this block of globals.
    const std::vector<GlobalValue*> &GVs = I->getGlobalsList();
    GlobalValue *First = GVs[0];
    for (unsigned i = 1, e = GVs.size(); i != e; ++i)
      GlobalECs.unionSets(First, GVs[i]);

    // Next, get the leader element.
    assert(First == GlobalECs.getLeaderValue(First) &&
           "First did not end up being the leader?");

    // Next, remove all globals from the scalar map that are not the leader.
    assert(GVs[0] == First && "First had to be at the front!");
    for (unsigned i = 1, e = GVs.size(); i != e; ++i) {
      ECGlobals.insert(GVs[i]);
      SM.erase(SM.find(GVs[i]));
    }

    // Finally, change the global node to only contain the leader.
    I->clearGlobals();
    I->addGlobal(First);
  }

  DEBUG(GG.AssertGraphOK());
}

/// EliminateUsesOfECGlobals - Once we have determined that some globals are in
/// really just equivalent to some other globals, remove the globals from the
/// specified DSGraph (if present), and merge any nodes with their leader nodes.
static void EliminateUsesOfECGlobals(DSGraph &G,
                                     const std::set<GlobalValue*> &ECGlobals) {
  DSScalarMap &SM = G.getScalarMap();
  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();

  bool MadeChange = false;
  for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
       GI != E; ) {
    GlobalValue *GV = *GI++;
    if (!ECGlobals.count(GV)) continue;

    const DSNodeHandle &GVNH = SM[GV];
    assert(!GVNH.isNull() && "Global has null NH!?");

    // Okay, this global is in some equivalence class.  Start by finding the
    // leader of the class.
    GlobalValue *Leader = GlobalECs.getLeaderValue(GV);

    // If the leader isn't already in the graph, insert it into the node
    // corresponding to GV.
    if (!SM.global_count(Leader)) {
      GVNH.getNode()->addGlobal(Leader);
      SM[Leader] = GVNH;
    } else {
      // Otherwise, the leader is in the graph, make sure the nodes are the
      // merged in the specified graph.
      const DSNodeHandle &LNH = SM[Leader];
      if (LNH.getNode() != GVNH.getNode())
        LNH.mergeWith(GVNH);
    }

    // Next step, remove the global from the DSNode.
    GVNH.getNode()->removeGlobal(GV);

    // Finally, remove the global from the ScalarMap.
    SM.erase(GV);
    MadeChange = true;
  }

  DEBUG(if(MadeChange) G.AssertGraphOK());
}

bool LocalDataStructures::runOnModule(Module &M) {

#ifdef LLVA_KERNEL
#if 0
  AllocList.push_back("kmalloc");
#endif
  AllocList.push_back("__vmalloc");
  AllocList.push_back("kmem_cache_alloc");
  AllocList.push_back("__alloc_bootmem");
  AllocList.push_back("__get_free_pages");
  AllocList.push_back("pseudo_alloc");
  AllocList.push_back("malloc");

#ifdef SVA_IO
  IOAllocList.push_back("__ioremap");
  IOAllocList.push_back("ioremap_nocache");
#endif

#if 0
  FreeList.push_back("kfree");
#endif
  FreeList.push_back("vfree");
  FreeList.push_back("free_pages");
  FreeList.push_back("kmem_cache_free");
  FreeList.push_back("pseudo_free");
  FreeList.push_back("free");

  //figure out all system call numbers
  Function* lrs = M.getNamedFunction("llva_register_syscall");
  if (lrs) 
    for (Value::use_iterator ii = lrs->use_begin(), ee = lrs->use_end(); ii != ee; ++ii) 
      if (CallInst* CI = dyn_cast<CallInst>(*ii))
        if ((CI->getCalledFunction() == lrs) && (isa<ConstantInt>(CI->getOperand(1)))) {
          ConstantInt * CNum = dyn_cast<ConstantInt>(CI->getOperand(1));
          unsigned int num = CNum->getSExtValue();
          Value* fun = CI->getOperand(2);
          if (ConstantExpr* CE = dyn_cast<ConstantExpr>(fun))
            if (CE->getOpcode() == Instruction::Cast)
              fun = CE->getOperand(0);
          if (Function* F = dyn_cast<Function>(fun))
              syscalls[num] = F;
        }

  //Add shadow globals for processor state
  new GlobalVariable(PointerType::get(Type::SByteTy), false, GlobalValue::InternalLinkage, Constant::getNullValue(PointerType::get(Type::SByteTy)), "llva.pgtable", &M);
  new GlobalVariable(PointerType::get(Type::SByteTy), false, GlobalValue::InternalLinkage, Constant::getNullValue(PointerType::get(Type::SByteTy)), "llva.invoke", &M);
  new GlobalVariable(PointerType::get(Type::SByteTy), false, GlobalValue::InternalLinkage, Constant::getNullValue(PointerType::get(Type::SByteTy)), "llva.kstackp", &M);

#endif

  const TargetData &TD = getAnalysis<TargetData>();

  // First step, build the globals graph.
  GlobalsGraph = new DSGraph(GlobalECs, TD);
  {
    GraphBuilder GGB(*GlobalsGraph);

    // Add initializers for all of the globals to the globals graph.
    for (Module::global_iterator I = M.global_begin(), E = M.global_end();
         I != E; ++I)
      if (!I->isExternal() && I->getName() != "llvm.used")
        GGB.mergeInGlobalInitializer(I);
  }

  // Next step, iterate through the nodes in the globals graph, unioning
  // together the globals into equivalence classes.
  std::set<GlobalValue*> ECGlobals;
  BuildGlobalECs(*GlobalsGraph, ECGlobals);
  DEBUG(std::cerr << "Eliminating " << ECGlobals.size() << " EC Globals!\n");
  ECGlobals.clear();

  // Calculate all of the graphs...
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isExternal())
      DSInfo.insert(std::make_pair(I, new DSGraph(GlobalECs, TD, *I,
                                                  GlobalsGraph)));
  GlobalsGraph->removeTriviallyDeadNodes();
  GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);

  // Now that we've computed all of the graphs, and merged all of the info into
  // the globals graph, see if we have further constrained the globals in the
  // program if so, update GlobalECs and remove the extraneous globals from the
  // program.
  BuildGlobalECs(*GlobalsGraph, ECGlobals);
  if (!ECGlobals.empty()) {
    DEBUG(std::cerr << "Eliminating " << ECGlobals.size() << " EC Globals!\n");
    for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
           E = DSInfo.end(); I != E; ++I)
      EliminateUsesOfECGlobals(*I->second, ECGlobals);
  }

  return true;
}

// releaseMemory - If the pass pipeline is done with this pass, we can release
// our memory... here...
//
void LocalDataStructures::releaseMemory() {
  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
         E = DSInfo.end(); I != E; ++I) {
    I->second->getReturnNodes().erase(I->first);
    if (I->second->getReturnNodes().empty())
      delete I->second;
  }

  // Empty map so next time memory is released, data structures are not
  // re-deleted.
  DSInfo.clear();
  delete GlobalsGraph;
  GlobalsGraph = 0;
}

