//===- BottomUpCallGraph.cpp - -----------------------------------------------//
// 
//                          The SAFECode Compiler 
//
// 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.
// 
//===----------------------------------------------------------------------===//
//
// I believe this pass does two things:
//  o) It attempts to improve upon the call graph calculated by DSA for those
//     call sites in which a callee was not found.
//  o) It finds functions that are part of Strongly Connected Components (SCCs)
//     in the call graph and marks them being a part of an SCC.
//
// FIXME:
//  I believe the fixup of the call graph is no longer necessary; DSA asserts
//  if it can't find a callee for a call instruction.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "bucg"

#include "dsa/DSGraph.h"
#include "dsa/DSNode.h"
#include "BottomUpCallGraph.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CallSite.h"
#include <iostream>

using namespace llvm;

static RegisterPass<BottomUpCallGraph> bucg("bucg","Call Graph from CBUDS");

namespace llvm {

char BottomUpCallGraph::ID = 0;

//
// This is needed because some call sites get merged away during DSA if they
// have the same inputs for instance.
// But for array bounds checking we need to get constraints from all the call
// sites
// So we have to get them some how.
//
bool
BottomUpCallGraph::runOnModule(Module &M) {
  EQTDDataStructures &CBU = getAnalysis<EQTDDataStructures>();

  const DSCallGraph & callGraph = CBU.getCallGraph();
  for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
    for (inst_iterator I = inst_begin(MI), E = inst_end(MI); I != E; ++I) {
      if (CallInst *CI = dyn_cast<CallInst>(&*I)) {
        DSCallGraph::iterator cI = callGraph.callee_begin(CI),
                              cE = callGraph.callee_end(CI);
        if (cI == cE) {
          // This call site is not included in the cbuds
          // so we need to extra stuff.
          CallSite CS = CallSite::get(CI);
          if (Function *FCI = dyn_cast<Function>(CI->getOperand(0))) {
            //if it is a direct call, we can just add it!
            FuncCallSiteMap[FCI].push_back(CS);
          } else {
            // Here comes the ugly part
            Function *parenFunc = CI->getParent()->getParent();
            DSNode *calleeNode = CBU.getDSGraph(*parenFunc)->getNodeForValue(CS.getCalledValue()).getNode();
            CalleeNodeCallSiteMap.insert(std::make_pair(calleeNode, CS));
          }
        }
      }
    }
  }

#if 0
  //
  // Get the set of instructions for which the points-to graph has callee
  // information.
  //
  std::vector<const Instruction *> Instructions;
  CBU.callee_get_keys (Instructions);
#endif

  //
  // Process each callee of each indirect call site.  We scan through each
  // indirect call site known by the EQTD DSA pass and process its callees.
  //
  DSCallGraph::key_iterator I = callGraph.key_begin();
  DSCallGraph::key_iterator E = callGraph.key_end();
  for (; I != E; ++I) {
    CallSite CS = *I;
    DSCallGraph::iterator i = callGraph.callee_begin(CS);
    DSCallGraph::iterator e = callGraph.callee_end(CS);
    for (; i != e; ++i) {
      const Function * Target = *i;
#if 0
      DOUT << "CALLEE: " << Target->getName()
           << " from : " << *(CI) << std::endl;
#endif
      FuncCallSiteMap[Target].push_back(CS);

      // FIXME:
      //  This is a very expensive way of doing it, 
      //
      // Determine if this is equivalent to any other callsites of this
      // function.
      Function *parenFunc = CS.getInstruction()->getParent()->getParent();
      DSNode *calleeNode = CBU.getDSGraph(*parenFunc)
                             ->getNodeForValue(CS.getCalledValue()).getNode();
      CalleeNodeCallSiteMapTy::const_iterator cI, cE;
      tie(cI, cE) = CalleeNodeCallSiteMap.equal_range(calleeNode);
      for (; cI != cE; ++cI) {
        //
        // All the call sites Target should also be added to the
        // funccallsitemap
        //
        FuncCallSiteMap[Target].push_back(cI->second);
      }
    }
  }
  figureOutSCCs(M);
  return false;
}


void
BottomUpCallGraph::visit (Function *f) {
  if (Visited.find(f) == Visited.end()) {
    // Record that we have now visited this function
    Visited.insert(f);

    //
    // If we have not visited this function before, that implies that the
    // function won't be on the stack; therefore, push it on stack
    //
    Stack.push_back(f);

    //
    // Visit all the functions that can call this function.
    //
    if (FuncCallSiteMap.count(f)) {
      std::vector<CallSite> & callsitelist = FuncCallSiteMap[f];
      for (unsigned idx = 0, sz = callsitelist.size(); idx != sz; ++idx) {
        Function *parent = callsitelist[idx].getInstruction()->getParent()
                                                             ->getParent();
        visit(parent);
      }
    }
    Stack.pop_back();
  } else {
    // We have already visited this function; check if it forms an SCC
    std::vector<Function*>::iterator res = std::find (Stack.begin(),
                                                      Stack.end(),
                                                      f);
    if (res != Stack.end()) {
      // Cycle detected.
      for (; res != Stack.end() ; ++res) {
        SccList.insert(*res);
      }
    }
  }
}

void
BottomUpCallGraph::figureOutSCCs (Module &M) {
  for (Module::iterator I = M.begin(), E= M.end(); I != E ; ++I) {
    visit(I);
  }
}
}

