//===- BottomUpClosure.cpp - Compute bottom-up interprocedural closure ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the BUDataStructures class, which represents the
// Bottom-Up Interprocedural closure of the data structure graph over the
// program.  This is useful for applications like pool allocation, but **not**
// applications like alias analysis.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "dsa-bu"
#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "llvm/Module.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"

using namespace llvm;

namespace {
  STATISTIC (MaxSCC, "Maximum SCC Size in Call Graph");
  STATISTIC (NumInlines, "Number of graphs inlined");
  STATISTIC (NumCallEdges, "Number of 'actual' call edges");

  RegisterPass<BUDataStructures>
  X("dsa-bu", "Bottom-up Data Structure Analysis");
}

char BUDataStructures::ID;

// run - Calculate the bottom up data structure graphs for each function in the
// program.
//
bool BUDataStructures::runOnModule(Module &M) {
  init(&getAnalysis<StdLibDataStructures>(), false, true, false, false );

  return runOnModuleInternal(M);
}

bool BUDataStructures::runOnModuleInternal(Module& M) {
  std::vector<const Function*> Stack;
  hash_map<const Function*, unsigned> ValMap;
  unsigned NextID = 1;

  Function *MainFunc = M.getFunction("main");
  if (MainFunc && !MainFunc->isDeclaration()) {
    calculateGraphs(MainFunc, Stack, NextID, ValMap);
    CloneAuxIntoGlobal(getDSGraph(*MainFunc));
  } else {
    DEBUG(errs() << debugname << ": No 'main' function found!\n");
  }

  // Calculate the graphs for any functions that are unreachable from main...
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() && !hasDSGraph(*I)) {
      if (MainFunc)
        DEBUG(errs() << debugname << ": Function unreachable from main: "
	      << I->getName() << "\n");
      calculateGraphs(I, Stack, NextID, ValMap);     // Calculate all graphs.
      CloneAuxIntoGlobal(getDSGraph(*I));
    }

  // If we computed any temporary indcallgraphs, free them now.
  for (std::map<std::vector<const Function*>,
         std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I =
         IndCallGraphMap.begin(), E = IndCallGraphMap.end(); I != E; ++I) {
    I->second.second.clear();  // Drop arg refs into the graph.
    delete I->second.first;
  }
  IndCallGraphMap.clear();

  // At the end of the bottom-up pass, the globals graph becomes complete.
  // FIXME: This is not the right way to do this, but it is sorta better than
  // nothing!  In particular, externally visible globals and unresolvable call
  // nodes at the end of the BU phase should make things that they point to
  // incomplete in the globals graph.
  //

  finalizeGlobals();

  GlobalsGraph->removeTriviallyDeadNodes(true);
  GlobalsGraph->maskIncompleteMarkers();

  // Mark external globals incomplete.
  GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);

  formGlobalECs();

  // Merge the globals variables (not the calls) from the globals graph back
  // into the main function's graph so that the main function contains all of
  // the information about global pools and GV usage in the program.
  if (MainFunc && !MainFunc->isDeclaration()) {
    DSGraph* MainGraph = getOrCreateGraph(MainFunc);
    const DSGraph* GG = MainGraph->getGlobalsGraph();
    ReachabilityCloner RC(MainGraph, GG,
                          DSGraph::DontCloneCallNodes |
                          DSGraph::DontCloneAuxCallNodes);

    // Clone the global nodes into this graph.
    for (DSScalarMap::global_iterator I = GG->getScalarMap().global_begin(),
           E = GG->getScalarMap().global_end(); I != E; ++I)
      if (isa<GlobalVariable>(*I))
        RC.getClonedNH(GG->getNodeForValue(*I));

    MainGraph->maskIncompleteMarkers();
    MainGraph->markIncompleteNodes(DSGraph::MarkFormalArgs |
                                   DSGraph::IgnoreGlobals);
  }

  NumCallEdges += callee_size();

  return false;
}

static inline bool nodeContainsExternalFunction(const DSNode *N) {
  std::vector<const Function*> Funcs;
  N->addFullFunctionList(Funcs);
  for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
    if (Funcs[i]->isDeclaration()) return true;
  return false;
}

void BUDataStructures::finalizeGlobals(void) {
  // Any unresolved call can be removed (resolved) if it does not contain
  // external functions and it is not reachable from any call that does
  // contain external functions
  std::set<DSCallSite> GoodCalls, BadCalls;
  for (DSGraph::afc_iterator ii = GlobalsGraph->afc_begin(), 
         ee = GlobalsGraph->afc_end(); ii != ee; ++ii)
    if (ii->isDirectCall() ||
        nodeContainsExternalFunction(ii->getCalleeNode()))
      BadCalls.insert(*ii);
    else
      GoodCalls.insert(*ii);
  hash_set<const DSNode*> reachable;
  for (std::set<DSCallSite>::iterator ii = BadCalls.begin(),
         ee = BadCalls.end(); ii != ee; ++ii) {
    ii->getRetVal().getNode()->markReachableNodes(reachable);
    for (unsigned x = 0; x < ii->getNumPtrArgs(); ++x)
      ii->getPtrArg(x).getNode()->markReachableNodes(reachable);
  }
  for (std::set<DSCallSite>::iterator ii = GoodCalls.begin(),
         ee = GoodCalls.end(); ii != ee; ++ii)
    if (reachable.find(ii->getCalleeNode()) == reachable.end())
      GlobalsGraph->getAuxFunctionCalls()
        .erase(std::find(GlobalsGraph->getAuxFunctionCalls().begin(),
                         GlobalsGraph->getAuxFunctionCalls().end(),
                         *ii));
  GlobalsGraph->getScalarMap().clear_scalars();
}

static void GetAllCallees(const DSCallSite &CS,
                          std::vector<const Function*> &Callees) {
  if (CS.isDirectCall()) {
    if (!CS.getCalleeFunc()->isDeclaration())
      Callees.push_back(CS.getCalleeFunc());
  } else if (!CS.getCalleeNode()->isIncompleteNode()) {
    // Get all callees.
    unsigned OldSize = Callees.size();
    CS.getCalleeNode()->addFullFunctionList(Callees);
    
    // If any of the callees are unresolvable, remove the whole batch!
    for (unsigned i = OldSize, e = Callees.size(); i != e; ++i)
      if (Callees[i]->isDeclaration()) {
        Callees.erase(Callees.begin()+OldSize, Callees.end());
        return;
      }
  }
}

static void GetAnyCallees(const DSCallSite &CS,
                          std::vector<const Function*> &Callees) {
  if (CS.isDirectCall()) {
    if (!CS.getCalleeFunc()->isDeclaration())
      Callees.push_back(CS.getCalleeFunc());
  } else {
    // Get all callees.
    unsigned OldSize = Callees.size();
    CS.getCalleeNode()->addFullFunctionList(Callees);
    
    // If any of the callees are unresolvable, remove them
    for (unsigned i = OldSize; i != Callees.size(); )
      if (Callees[i]->isDeclaration()) {
        Callees.erase(Callees.begin()+i);
      } else 
        ++i;
  }
}

/// GetAllAuxCallees - Return a list containing all of the resolvable callees in
/// the aux list for the specified graph in the Callees vector.
static void GetAllAuxCallees(DSGraph* G, std::vector<const Function*> &Callees) {
  Callees.clear();
  for (DSGraph::afc_iterator I = G->afc_begin(), E = G->afc_end(); I != E; ++I)
    GetAllCallees(*I, Callees);
}

/// GetAnyAuxCallees - Return a list containing all of the callees in
/// the aux list for the specified graph in the Callees vector.
static void GetAnyAuxCallees(DSGraph* G, std::vector<const Function*> &Callees) {
  Callees.clear();
  for (DSGraph::afc_iterator I = G->afc_begin(), E = G->afc_end(); I != E; ++I)
    GetAnyCallees(*I, Callees);
}

unsigned BUDataStructures::calculateGraphs(const Function *F,
                                           std::vector<const Function*> &Stack,
                                           unsigned &NextID,
                                           hash_map<const Function*, unsigned> &ValMap) {
  assert(!ValMap.count(F) && "Shouldn't revisit functions!");
  unsigned Min = NextID++, MyID = Min;
  ValMap[F] = Min;
  Stack.push_back(F);

  // FIXME!  This test should be generalized to be any function that we have
  // already processed, in the case when there isn't a main or there are
  // unreachable functions!
  if (F->isDeclaration()) {   // sprintf, fprintf, sscanf, etc...
    // No callees!
    Stack.pop_back();
    ValMap[F] = ~0;
    return Min;
  }

  DSGraph* Graph = getOrCreateGraph(F);

  // Find all callee functions.
  std::vector<const Function*> CalleeFunctions;
  GetAnyAuxCallees(Graph, CalleeFunctions);
  std::sort(CalleeFunctions.begin(), CalleeFunctions.end());
  std::vector<const Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
  CalleeFunctions.resize(uid - CalleeFunctions.begin());

  std::vector<const Function*> PreResolvedFuncs;
  GetAllAuxCallees(Graph, PreResolvedFuncs);
  std::sort(PreResolvedFuncs.begin(), PreResolvedFuncs.end());
  uid = std::unique(PreResolvedFuncs.begin(), PreResolvedFuncs.end());
  PreResolvedFuncs.resize(uid - PreResolvedFuncs.begin());
  
  // The edges out of the current node are the call site targets...
  for (unsigned i = 0, e = CalleeFunctions.size(); i != e; ++i) {
    const Function *Callee = CalleeFunctions[i];
    unsigned M;
    // Have we visited the destination function yet?
    hash_map<const Function*, unsigned>::iterator It = ValMap.find(Callee);
    if (It == ValMap.end())  // No, visit it now.
      M = calculateGraphs(Callee, Stack, NextID, ValMap);
    else                    // Yes, get it's number.
      M = It->second;
    if (M < Min) Min = M;
  }

  assert(ValMap[F] == MyID && "SCC construction assumption wrong!");
  if (Min != MyID)
    return Min;         // This is part of a larger SCC!

  // If this is a new SCC, process it now.
  if (Stack.back() == F) {           // Special case the single "SCC" case here.
    DEBUG(errs() << "Visiting single node SCC #: " << MyID << " fn: "
	  << F->getName() << "\n");
    Stack.pop_back();
    DEBUG(errs() << "  [BU] Calculating graph for: " << F->getName()<< "\n");
    calculateGraph(Graph);
    DEBUG(errs() << "  [BU] Done inlining: " << F->getName() << " ["
	  << Graph->getGraphSize() << "+" << Graph->getAuxFunctionCalls().size()
	  << "]\n");

    if (MaxSCC < 1) MaxSCC = 1;

    // Should we revisit the graph?  Only do it if there are now new resolvable
    // callees or new callees
    std::vector<const Function*> NewCalleeFuncs;
    GetAnyAuxCallees(Graph, NewCalleeFuncs);
    std::sort(NewCalleeFuncs.begin(), NewCalleeFuncs.end());
    std::vector<const Function*>::iterator uid = std::unique(NewCalleeFuncs.begin(), NewCalleeFuncs.end());
    NewCalleeFuncs.resize(uid - NewCalleeFuncs.begin());
    uid = std::set_difference(NewCalleeFuncs.begin(), NewCalleeFuncs.end(),
                              CalleeFunctions.begin(), CalleeFunctions.end(),
                              NewCalleeFuncs.begin());
    NewCalleeFuncs.resize(uid - NewCalleeFuncs.begin());

    std::vector<const Function*> ResolvedFuncs;
    GetAllAuxCallees(Graph, ResolvedFuncs);
    std::sort(ResolvedFuncs.begin(), ResolvedFuncs.end());
    uid = std::unique(ResolvedFuncs.begin(), ResolvedFuncs.end());
    ResolvedFuncs.resize(uid - ResolvedFuncs.begin());
    uid = std::set_difference(ResolvedFuncs.begin(), ResolvedFuncs.end(),
                              PreResolvedFuncs.begin(), PreResolvedFuncs.end(),
                              ResolvedFuncs.begin());
    ResolvedFuncs.resize(uid - ResolvedFuncs.begin());

    if (ResolvedFuncs.size() || NewCalleeFuncs.size()) {
      DEBUG(errs() << "Recalculating " << F->getName() << " due to new knowledge\n");
      ValMap.erase(F);
      return calculateGraphs(F, Stack, NextID, ValMap);
    } else {
      ValMap[F] = ~0U;
    }
    //propagate incomplete call nodes
    inlineUnresolved(Graph);
    return MyID;

  } else {
    // SCCFunctions - Keep track of the functions in the current SCC
    //
    std::vector<DSGraph*> SCCGraphs;

    unsigned SCCSize = 1;
    const Function *NF = Stack.back();
    ValMap[NF] = ~0U;
    DSGraph* SCCGraph = getDSGraph(*NF);

    // First thing first, collapse all of the DSGraphs into a single graph for
    // the entire SCC.  Splice all of the graphs into one and discard all of the
    // old graphs.
    //
    while (NF != F) {
      Stack.pop_back();
      NF = Stack.back();
      ValMap[NF] = ~0U;

      DSGraph* NFG = getDSGraph(*NF);

      if (NFG != SCCGraph) {
        // Update the Function -> DSG map.
        for (DSGraph::retnodes_iterator I = NFG->retnodes_begin(),
               E = NFG->retnodes_end(); I != E; ++I)
          setDSGraph(*I->first, SCCGraph);
        
        SCCGraph->spliceFrom(NFG);
        delete NFG;
        ++SCCSize;
      }
    }
    Stack.pop_back();

    DEBUG(errs() << "Calculating graph for SCC #: " << MyID << " of size: "
	  << SCCSize << "\n");

    // Compute the Max SCC Size.
    if (MaxSCC < SCCSize)
      MaxSCC = SCCSize;

    // Clean up the graph before we start inlining a bunch again...
    SCCGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);

    // Now that we have one big happy family, resolve all of the call sites in
    // the graph...
    calculateGraph(SCCGraph);
    DEBUG(errs() << "  [BU] Done inlining SCC  [" << SCCGraph->getGraphSize()
	  << "+" << SCCGraph->getAuxFunctionCalls().size() << "]\n"
	  << "DONE with SCC #: " << MyID << "\n");

    // We never have to revisit "SCC" processed functions...
    //propagate incomplete call nodes
    inlineUnresolved(SCCGraph);
    return MyID;
  }

  return MyID;  // == Min
}

void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) {
  DSGraph* GG = G->getGlobalsGraph();
  ReachabilityCloner RC(GG, G, 0);

  for(DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end();
      ii != ee; ++ii) {
    //cerr << "Pushing " << ii->getCallSite().getInstruction()->getOperand(0) << "\n";
    //If we can, merge with an existing call site for this instruction
    if (GG->hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) {
      DSGraph::afc_iterator GGii;
      for(GGii = GG->afc_begin(); GGii != GG->afc_end(); ++GGii)
        if (GGii->getCallSite().getInstruction()->getOperand(0) ==
            ii->getCallSite().getInstruction()->getOperand(0))
          break;
      if (GGii != GG->afc_end())
        RC.cloneCallSite(*ii).mergeWith(*GGii);
      else
        GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
    } else {
      GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
    }
  }
}

void BUDataStructures::calculateGraph(DSGraph* Graph) {
  DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());

  // If this graph contains the main function, clone the globals graph into this
  // graph before we inline callees and other fun stuff.
  bool ContainsMain = false;
  DSGraph::ReturnNodesTy &ReturnNodes = Graph->getReturnNodes();

  for (DSGraph::ReturnNodesTy::iterator I = ReturnNodes.begin(),
         E = ReturnNodes.end(); I != E; ++I)
    if (I->first->hasExternalLinkage() && I->first->getName() == "main") {
      ContainsMain = true;
      break;
    }

  // If this graph contains main, copy the contents of the globals graph over.
  // Note that this is *required* for correctness.  If a callee contains a use
  // of a global, we have to make sure to link up nodes due to global-argument
  // bindings.
  if (ContainsMain || ReInlineGlobals) {
    const DSGraph* GG = Graph->getGlobalsGraph();
    ReachabilityCloner RC(Graph, GG,
                          DSGraph::DontCloneCallNodes |
                          DSGraph::DontCloneAuxCallNodes);
    if (ContainsMain) {
      // Clone the global nodes into this graph.
      for (DSScalarMap::global_iterator I = GG->getScalarMap().global_begin(),
             E = GG->getScalarMap().global_end(); I != E; ++I)
        if (isa<GlobalVariable>(*I))
          RC.getClonedNH(GG->getNodeForValue(*I));
    } else {
      // Clone used the global nodes into this graph.
      for (DSScalarMap::global_iterator I = Graph->getScalarMap().global_begin(),
             E = Graph->getScalarMap().global_end(); I != E; ++I)
        if (isa<GlobalVariable>(*I))
          RC.getClonedNH(GG->getNodeForValue(*I));
    }
  }

  // Move our call site list into TempFCs so that inline call sites go into the
  // new call site list and doesn't invalidate our iterators!
  std::list<DSCallSite> TempFCs;
  std::list<DSCallSite> &AuxCallsList = Graph->getAuxFunctionCalls();
  TempFCs.swap(AuxCallsList);

  std::vector<const Function*> CalledFuncs;
  while (!TempFCs.empty()) {
    DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
    
    DSCallSite &CS = *TempFCs.begin();
    Instruction *TheCall = CS.getCallSite().getInstruction();

    CalledFuncs.clear();

    GetAllCallees(CS, CalledFuncs);
    bool isComplete = true;

    if (CalledFuncs.empty()) {
      // Remember that we could not resolve this yet!
      isComplete = false;
      GetAnyCallees(CS, CalledFuncs);
      if (useCallGraph)
        for (callee_iterator ii = callee_begin(CS.getCallSite().getInstruction()),
               ee = callee_end(CS.getCallSite().getInstruction()); ii != ee; ++ii)
          CalledFuncs.push_back(*ii);
      std::sort(CalledFuncs.begin(), CalledFuncs.end());
      std::vector<const Function*>::iterator uid = std::unique(CalledFuncs.begin(), CalledFuncs.end());
      CalledFuncs.resize(uid - CalledFuncs.begin());
    }

    DSGraph *GI;
    
    for (std::vector<const Function*>::iterator ii = CalledFuncs.begin(), ee = CalledFuncs.end();
         ii != ee; ++ii) 
      callee_add(TheCall, *ii);

    if (CalledFuncs.size() == 1 && (isComplete || hasDSGraph(*CalledFuncs[0]))) {
      const Function *Callee = CalledFuncs[0];

      // Get the data structure graph for the called function.
      GI = getDSGraph(*Callee);  // Graph to inline
      DEBUG(GI->AssertGraphOK(); GI->getGlobalsGraph()->AssertGraphOK());
      DEBUG(errs() << "    Inlining graph for " << Callee->getName()
	    << "[" << GI->getGraphSize() << "+"
	    << GI->getAuxFunctionCalls().size() << "] into '"
	    << Graph->getFunctionNames() << "' [" << Graph->getGraphSize() <<"+"
	    << Graph->getAuxFunctionCalls().size() << "]\n");
      Graph->mergeInGraph(CS, *Callee, *GI,
                          DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes|
                          (isComplete?0:DSGraph::DontCloneAuxCallNodes));
      ++NumInlines;
      DEBUG(Graph->AssertGraphOK(););
    } else if (CalledFuncs.size() > 1) {
      DEBUG(errs() << "In Fns: " << Graph->getFunctionNames() << "\n");
      DEBUG(errs() << "  calls " << CalledFuncs.size()
            << " fns from site: " << CS.getCallSite().getInstruction()
            << "  " << *CS.getCallSite().getInstruction());
      DEBUG(errs() << "   Fns =");
      unsigned NumPrinted = 0;
      
      for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
             E = CalledFuncs.end(); I != E; ++I)
        if (NumPrinted++ < 8) {
	  DEBUG(errs() << " " << (*I)->getName());
	}
      DEBUG(errs() << "\n");
      
      if (!isComplete) {
        for (unsigned x = 0; x < CalledFuncs.size(); )
          if (!hasDSGraph(*CalledFuncs[x]))
            CalledFuncs.erase(CalledFuncs.begin() + x);
          else
            ++x;
      }
      if (CalledFuncs.size()) {
        // See if we already computed a graph for this set of callees.
        std::sort(CalledFuncs.begin(), CalledFuncs.end());
        std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
          IndCallGraphMap[CalledFuncs];
        
        if (IndCallGraph.first == 0) {
          std::vector<const Function*>::iterator I = CalledFuncs.begin(),
            E = CalledFuncs.end();
          
          // Start with a copy of the first graph.
          GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
          GI->setGlobalsGraph(Graph->getGlobalsGraph());
          std::vector<DSNodeHandle> &Args = IndCallGraph.second;
          
          // Get the argument nodes for the first callee.  The return value is
          // the 0th index in the vector.
          GI->getFunctionArgumentsForCall(*I, Args);
          
          // Merge all of the other callees into this graph.
          for (++I; I != E; ++I) {
            // If the graph already contains the nodes for the function, don't
            // bother merging it in again.
            if (!GI->containsFunction(*I)) {
              GI->cloneInto(getDSGraph(**I));
              ++NumInlines;
            }
            
            std::vector<DSNodeHandle> NextArgs;
            GI->getFunctionArgumentsForCall(*I, NextArgs);
            unsigned i = 0, e = Args.size();
            for (; i != e; ++i) {
              if (i == NextArgs.size()) break;
              Args[i].mergeWith(NextArgs[i]);
            }
            for (e = NextArgs.size(); i != e; ++i)
              Args.push_back(NextArgs[i]);
          }
          
          // Clean up the final graph!
          GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
        } else {
          DEBUG(errs() << "***\n*** RECYCLED GRAPH ***\n***\n");
        }
        
        GI = IndCallGraph.first;
        
        // Merge the unified graph into this graph now.
        DEBUG(errs() << "    Inlining multi callee graph "
	      << "[" << GI->getGraphSize() << "+"
	      << GI->getAuxFunctionCalls().size() << "] into '"
	      << Graph->getFunctionNames() << "' [" << Graph->getGraphSize() <<"+"
	      << Graph->getAuxFunctionCalls().size() << "]\n");
        
        Graph->mergeInGraph(CS, IndCallGraph.second, *GI,
                            DSGraph::StripAllocaBit |
                            DSGraph::DontCloneCallNodes|
                            (isComplete?0:DSGraph::DontCloneAuxCallNodes));
        ++NumInlines;
      }
    }
    DEBUG(Graph->AssertGraphOK(););
    DEBUG(Graph->getGlobalsGraph()->AssertGraphOK());
    if (!isComplete)
      AuxCallsList.push_front(CS);
    TempFCs.erase(TempFCs.begin());
  }

  // Recompute the Incomplete markers
  Graph->maskIncompleteMarkers();
  Graph->markIncompleteNodes(DSGraph::MarkFormalArgs);

  // Delete dead nodes.  Treat globals that are unreachable but that can
  // reach live nodes as live.
  Graph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);

  // When this graph is finalized, clone the globals in the graph into the
  // globals graph to make sure it has everything, from all graphs.
  DSScalarMap &MainSM = Graph->getScalarMap();
  ReachabilityCloner RC(GlobalsGraph, Graph, DSGraph::StripAllocaBit);

  // Clone everything reachable from globals in the function graph into the
  // globals graph.
  for (DSScalarMap::global_iterator I = MainSM.global_begin(),
         E = MainSM.global_end(); I != E; ++I)
    RC.getClonedNH(MainSM[*I]);

  //Graph.writeGraphToFile(cerr, "bu_" + F.getName());
}

void BUDataStructures::inlineUnresolved(DSGraph* Graph) {

  // Move our call site list into TempFCs so that inline call sites go into the
  // new call site list and doesn't invalidate our iterators!
  std::list<DSCallSite> TempFCs = Graph->getAuxFunctionCalls();

  for (DSGraph::afc_iterator aii = TempFCs.begin(), aee = TempFCs.end(); 
       aii != aee; ++aii) {
    std::vector<const Function*> CalledFuncs;
    DSCallSite CS = *aii;
    GetAnyCallees(CS, CalledFuncs);
    if (CalledFuncs.empty())
      continue;

    DSGraph *GI;
    Instruction *TheCall = CS.getCallSite().getInstruction();  

    for (std::vector<const Function*>::iterator ii = CalledFuncs.begin(), ee = CalledFuncs.end();
         ii != ee; ++ii)
      callee_add(TheCall, *ii);

    if (CalledFuncs.size() == 1 && hasDSGraph(*CalledFuncs[0])) {
      const Function *Callee = CalledFuncs[0];

      // Get the data structure graph for the called function.
      GI = getDSGraph(*Callee);  // Graph to inline
      if (GI == Graph) continue;
      DEBUG(errs() << "    Inlining graph for " << Callee->getName()
	    << "[" << GI->getGraphSize() << "+"
	    << GI->getAuxFunctionCalls().size() << "] into '"
	    << Graph->getFunctionNames() << "' [" << Graph->getGraphSize() <<"+"
	    << Graph->getAuxFunctionCalls().size() << "]\n");
      Graph->mergeInGraph(CS, *Callee, *GI,
                         DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
      ++NumInlines;
    } else {
      DEBUG(errs() << "In Fns: " << Graph->getFunctionNames() << "\n");
      DEBUG(std::cerr << "  calls " << CalledFuncs.size()
            << " fns from site: " << CS.getCallSite().getInstruction()
            << "  " << *CS.getCallSite().getInstruction());
      DEBUG(errs() << "   Fns =");
      unsigned NumPrinted = 0;
      
      for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
             E = CalledFuncs.end(); I != E; ++I)
        if (NumPrinted++ < 8) {
	  DEBUG(errs() << " " << (*I)->getName());
	}
      DEBUG(errs() << "\n");
      
      for (unsigned x = 0; x < CalledFuncs.size(); )
        if (!hasDSGraph(*CalledFuncs[x]))
          CalledFuncs.erase(CalledFuncs.begin() + x);
        else
          ++x;
      if (!CalledFuncs.size())
        continue;

      // See if we already computed a graph for this set of callees.
      std::sort(CalledFuncs.begin(), CalledFuncs.end());
      std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
        IndCallGraphMap[CalledFuncs];
      
      if (IndCallGraph.first == Graph) continue;

      if (IndCallGraph.first == 0) {
        std::vector<const Function*>::iterator I = CalledFuncs.begin(),
          E = CalledFuncs.end();
        
        // Start with a copy of the first graph.
        GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
        GI->setGlobalsGraph(Graph->getGlobalsGraph());
        std::vector<DSNodeHandle> &Args = IndCallGraph.second;
        
        // Get the argument nodes for the first callee.  The return value is
        // the 0th index in the vector.
        GI->getFunctionArgumentsForCall(*I, Args);
        
        // Merge all of the other callees into this graph.
        for (++I; I != E; ++I) {
          // If the graph already contains the nodes for the function, don't
          // bother merging it in again.
          if (!GI->containsFunction(*I)) {
            GI->cloneInto(getDSGraph(**I));
            ++NumInlines;
          }
          
          std::vector<DSNodeHandle> NextArgs;
          GI->getFunctionArgumentsForCall(*I, NextArgs);
          unsigned i = 0, e = Args.size();
          for (; i != e; ++i) {
            if (i == NextArgs.size()) break;
            Args[i].mergeWith(NextArgs[i]);
          }
          for (e = NextArgs.size(); i != e; ++i)
            Args.push_back(NextArgs[i]);
        }
        
        // Clean up the final graph!
        GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
      } else {
        DEBUG(errs() << "***\n*** RECYCLED GRAPH ***\n***\n");
      }
      
      GI = IndCallGraph.first;
      
      // Merge the unified graph into this graph now.
      DEBUG(errs() << "    Inlining multi callee graph "
            << "[" << GI->getGraphSize() << "+"
            << GI->getAuxFunctionCalls().size() << "] into '"
            << Graph->getFunctionNames() << "' [" << Graph->getGraphSize() <<"+"
            << Graph->getAuxFunctionCalls().size() << "]\n" );
      
      Graph->mergeInGraph(CS, IndCallGraph.second, *GI,
                          DSGraph::StripAllocaBit |
                          DSGraph::DontCloneCallNodes);
      ++NumInlines;
    }
  }

  // Recompute the Incomplete markers
  Graph->maskIncompleteMarkers();
  Graph->markIncompleteNodes(DSGraph::MarkFormalArgs);

  // Delete dead nodes.  Treat globals that are unreachable but that can
  // reach live nodes as live.
  Graph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);

  // When this graph is finalized, clone the globals in the graph into the
  // globals graph to make sure it has everything, from all graphs.
  DSScalarMap &MainSM = Graph->getScalarMap();
  ReachabilityCloner RC(GlobalsGraph, Graph, DSGraph::StripAllocaBit);

  // Clone everything reachable from globals in the function graph into the
  // globals graph.
  for (DSScalarMap::global_iterator I = MainSM.global_begin(),
         E = MainSM.global_end(); I != E; ++I)
    RC.getClonedNH(MainSM[*I]);

  //Graph.writeGraphToFile(cerr, "bu_" + F.getName());
}
