//===-- insert.cpp - Insert SAFECode Run-time Checks ----------------------===//
//
//                     SAFECode
//
// 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 insertion of SAFECode's run-time checks.
//
//===----------------------------------------------------------------------===//

#include "safecode/Config/config.h"
#include "InsertPoolChecks.h"
#include "SCUtils.h"
#include "llvm/Instruction.h"
#include "llvm/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/Analysis/LoopInfo.h" 
#include <iostream>
#include <vector>
#include <set>

using namespace llvm;

extern Value *getRepresentativeMetaPD(Value *);

RegisterPass<PreInsertPoolChecks> pipc ("presafecode", "prepare for SAFECode");
RegisterPass<InsertPoolChecks>     ipc ("safecode",    "insert runtime checks");

cl::opt<bool> EnableSplitChecks  ("enable-splitchecks", cl::Hidden,
                                  cl::init(false),
                                  cl::desc("Split lookup and checks"));

cl::opt<bool> InsertPoolChecksForArrays("boundschecks-usepoolchecks",
                cl::Hidden, cl::init(false),
                cl::desc("Insert pool checks instead of exact bounds checks"));
  
// Options for Enabling/Disabling the Insertion of Various Checks
cl::opt<bool> EnableUnknownChecks ("enable-unknownchecks", cl::Hidden,
                                   cl::init(false),
                                   cl::desc("Enable Checks on Incomplete/Unknown Nodes"));

cl::opt<bool> EnableNullChecks  ("enable-nullchecks", cl::Hidden,
                                cl::init(false),
                                cl::desc("Enable Checks on NULL Pools"));


cl::opt<bool> DisableRegisterGlobals ("disable-regglobals", cl::Hidden,
                                cl::init(false),
                                cl::desc("Do not register globals"));

cl::opt<bool> DisableLSChecks  ("disable-lschecks", cl::Hidden,
                                cl::init(false),
                                cl::desc("Disable Load/Store Checks"));

cl::opt<bool> DisableGEPChecks ("disable-gepchecks", cl::Hidden,
                                cl::init(false),
                                cl::desc("Disable GetElementPtr(GEP) Checks"));

cl::opt<bool> DisableStackChecks ("disable-stackchecks", cl::Hidden,
                                  cl::init(false),
                                  cl::desc("Disable Stack Checks"));

cl::opt<bool> DisableFuncChecks ("disable-funcchecks", cl::Hidden,
                                  cl::init(false),
                                  cl::desc("Disable Function Call Checks"));

cl::opt<bool> DisableIntrinsicChecks ("disable-intrinchecks", cl::Hidden,
                                      cl::init(false),
                                      cl::desc("Disable Intrinsic Checks"));

cl::opt<bool> EnableMonotonicOptimisation("enable-monotonic", cl::Hidden,
                                          cl::init(false),
                   cl::desc("Enable LICM for bounds checks on monotonic loops"));

// Options for where to insert various initialization code
cl::opt<string> InitFunctionName ("initfunc",
                                  cl::desc("Specify name of initialization "
                                           "function"),
                                  cl::value_desc("function name"));

// Pass Statistics
static Statistic<> NullChecks ("safecode",
                               "Poolchecks with NULL pool descriptor");
static Statistic<> FullChecks ("safecode",
                               "Poolchecks with non-NULL pool descriptor");
static Statistic<> MissChecks ("safecode",
                               "Poolchecks omitted due to bad pool descriptor");
static Statistic<> PoolChecks ("safecode", "Poolchecks Added");

static Statistic<> FuncChecks ("safecode", "Indirect Call Checks Added");
static Statistic<> MissedFuncChecks ("safecode", "Indirect Call Checks Missed");
static Statistic<> SavedPoolChecks ("safecode", "Pool Checks Performed on Checked Pointers");
static Statistic<> AlignChecks ("safecode", "Number of alignment checks required");
static Statistic<> AlignLSChecks ("safecode", "Number of alignment on load/store checks required");

// Bounds Check Statistics
static Statistic<> BoundsChecks     ("safecode",
                                     "Total bounds checks inserted");
static Statistic<> IBoundsChecks    ("safecode",
                                     "Bounds checks with incomplete DSNode");
static Statistic<> UBoundsChecks    ("safecode",
                                     "Bounds checks with unknown DSNode");
static Statistic<> ABoundsChecks    ("safecode",
                                     "Bounds checks with stack DSNode");
static Statistic<> NullBoundsChecks ("safecode",
                                     "Missed bounds checks - NULL pool handle");
static Statistic<> NoSHGBoundsChecks ("safecode",
                                      "Missed bounds checks - no SHG DSNode");


static Statistic<> MissedIncompleteChecks ("safecode",
                               "Poolchecks missed because of incompleteness");
static Statistic<> MissedMultDimArrayChecks ("safecode",
                                             "Multi-dimensional array checks");

static Statistic<> MissedGlobalChecks ("safecode", "Missed global checks");
static Statistic<> MissedNullChecks   ("safecode", "Missed PD checks");

// Exact Check Statistics
static Statistic<> ExactChecks        ("safecode", "Exactchecks inserted");
static Statistic<> ConstExactChecks   ("safecode", "Omitted Exactchecks with constant arguments");
static Statistic<> ZeroFuncChecks     ("safecode", "Indirect Call Checks with Zero Targets");
 
// Object registration statistics
static Statistic<> StackRegisters     ("safecode", "Stack registrations");
static Statistic<> SavedRegAllocs     ("safecode", "Stack registrations avoided");

// Other statistics
static Statistic<> StructGEPsRemoved  ("safecode", "Structure GEP Checks Removed");

//MonotonicOpts
static Statistic<> MonotonicOpts  ("safecode", "Number of monotonic LICM bounds check optimisations");

// The set of values that already have run-time checks
static std::set<Value *> CheckedValues;

////////////////////////////////////////////////////////////////////////////
// Static Functions
////////////////////////////////////////////////////////////////////////////

//Do not replace these with check results
static std::set<Value*> AddedValues;

static GlobalVariable*
makeMetaPool(Module* M, DSNode* N) {
  //Here we insert a global meta pool
  //Now create a meta pool for this value, DSN Node
  const Type * VoidPtrType = PointerType::get(Type::SByteTy);
  std::vector<const Type*> MPTV;
  for (int x = 0; x < 9; ++x)
    MPTV.push_back(VoidPtrType);
  // Add the types for the hit cache
  MPTV.push_back(Type::UIntTy);
  MPTV.push_back(ArrayType::get (Type::UIntTy, 4));
  MPTV.push_back(ArrayType::get (Type::UIntTy, 4));
  MPTV.push_back(ArrayType::get (VoidPtrType, 4));

  const StructType* MPT = StructType::get(MPTV);

  static int x = 0;
  std::string Name = "_metaPool_";
 
  unsigned Flags = N ? N->getMP()->getFlags() : 0;
  if(Flags & DSNode::Incomplete)
    Name += "I";
  if(Flags & DSNode::UnknownNode)
    Name += "U";
  if(Flags & DSNode::AllocaNode)
    Name += "A";
  if(Flags & DSNode::GlobalNode)
    Name += "G";
  if(Flags & DSNode::HeapNode)
    Name += "H";
  if( N && N->isNodeCompletelyFolded())
    Name += "F";
  Name += "_";
  char c[100];
  snprintf(c, sizeof(c), "%d", x);
  Name += c;
  Name += "_";
  ++x;

  return new GlobalVariable(
                            /*type=*/ MPT,
                            /*isConstant=*/ false,
                            /*Linkage=*/ GlobalValue::InternalLinkage,
                            /*initializer=*/ Constant::getNullValue(MPT),
                            /*name=*/ Name,
                            /*parent=*/ M );
}

Value *
PreInsertPoolChecks::createPoolHandle (Module & M, DSNode * Node) {
  // If there is no node, return NULL.
  if (!Node) return 0;

  // Get the DSNode's MetaPool.  If it doesn't have one, return NULL.
  MetaPool * MP = Node->getMP();
  if (!MP) return 0;

  // If the MetaPool global variable has already been created, then simply
  // return it.  Otherwise, create one.
  if (!(MP->getMetaPoolValue()))
    MP->setMetaPoolValue (makeMetaPool (&M, Node));  
  return (MP->getMetaPoolValue());
}


Value *
PreInsertPoolChecks::createPoolHandle (const Value * V, Function * F) {
  //
  // Get the DSNode from the Top Down DSGraph.
  //
  DSGraph &TDG =  TDPass->getDSGraph(*F);
  DSNode *Node = TDG.getNodeForValue((Value *)V).getNode();

  // If there is no node, return NULL.
  if (!Node) return 0;

  // Get the DSNode's MetaPool.  If it doesn't have one, return NULL.
  MetaPool * MP = Node->getMP();
  if (!MP) return 0;

  // If the MetaPool global variable has already been created, then simply
  // return it.  Otherwise, create one.
  if (!(MP->getMetaPoolValue()))
    MP->setMetaPoolValue (makeMetaPool (F->getParent(), Node));  
  return (MP->getMetaPoolValue());
}

static void
AddCallToRegFunc (Function* F, GlobalVariable* GV, Function* PR, Value* PH,
                  Value* AllocSize) {
  //
  // First, make sure that we're not registering an external zero-sized global.
  // These are caused by the following C construct and should never be checked:
  //  extern variable[];
  //
  ConstantInt * C;
  if (GV->isExternal())
    if ((C = dyn_cast<ConstantInt>(AllocSize)) && (!(C->getZExtValue())))
      return;

  const Type *VoidPtrType = PointerType::get(Type::SByteTy); 

  assert(PH && "No PoolHandle for Global!");

  BasicBlock::iterator InsertPt = F->getEntryBlock().begin();
  Instruction *GVCasted = new CastInst(GV, VoidPtrType, GV->getName()+"casted",InsertPt);
  Value *PHCasted = new CastInst(PH, VoidPtrType, PH->getName()+"casted",InsertPt);
  AllocSize = castTo (AllocSize, Type::UIntTy, InsertPt);
  std::vector<Value *> args (1, PHCasted);
  args.push_back (GVCasted);
  args.push_back (AllocSize);
  new CallInst(PR, args, "", InsertPt);
}

////////////////////////////////////////////////////////////////////////////
// Class: PreInsertPoolChecks
////////////////////////////////////////////////////////////////////////////

//
// Method: runOnModule()
//
// Description:
//  This method is called by the pass manager.  The job of this class is to
//  create any global variables and inter-procedural changes that cannot be
//  done in the doInitialization() method of the InsertPoolChecks class.
//
bool
PreInsertPoolChecks::runOnModule (Module & M) {
  // Retrieve the analysis results from other passes
  cuaPass = &getAnalysis<ConvertUnsafeAllocas>();
  TDPass  = &getAnalysis<TDDataStructures>();
  TD      = &getAnalysis<TargetData>();

  // Add prototypes for the run-time checks to the module
  addPoolCheckProto (M);

  // Register global arrays and collapsed nodes with global pools
  if (!DisableRegisterGlobals) registerGlobalArraysWithGlobalPools(M);

  //
  // Create a MetaPool global variable for every DSNode that we might
  // encounter.
  //
  Module::iterator mI = M.begin(), mE = M.end();
  for ( ; mI != mE; ++mI) {
    Function *F = mI;

    // Skip functions that are external
    if (F->isExternal()) continue;

    // Skip the poolcheckglobals() function because it won't have a DSGraph
    if (F->getName() == "poolcheckglobals") continue;

    // Create a MetaPool variable for each DSNode in the DSGraph.
    DSGraph & TDG = TDPass->getDSGraph(*F);
    DSGraph::node_iterator NI = TDG.node_begin(), NE = TDG.node_end();
    while (NI != NE) {
      addLinksNeedingAlignment (NI);
      createPoolHandle (M, NI);
      ++NI;
    }
  }
}

//
// Method: addLinksNeedingAlignment()
//
// Description:
//  Determine if this DSNode has any pointers to DSNodes which will require
//  alignment checks.  If so, add those DSNodes to the set of DSNodes needing
//  alignment checks.  Note that we do not determine if the *given* node needs
//  alignment checks.
//
void
PreInsertPoolChecks::addLinksNeedingAlignment (DSNode * Node) {
  //
  // Determine whether an alignment check is needed.  This occurs when a DSNode
  // is type unknown (collapsed) but has pointers to type known (uncollapsed)
  // DSNodes.
  //
  if ((Node) && (Node->isNodeCompletelyFolded())) {
    for (unsigned i = 0 ; i < Node->getNumLinks(); ++i) {
      DSNode * LinkNode = Node->getLink(i).getNode();
      if (LinkNode && (!(LinkNode->isNodeCompletelyFolded()))) {
        AlignmentNodes.insert (LinkNode);
      }
    }
  }
}

void
PreInsertPoolChecks::addPoolCheckProto(Module &M) {
  const Type * VoidPtrType = PointerType::get(Type::SByteTy);
#if 0
  const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
  //	StructType::get(make_vector<const Type*>(VoidPtrType, VoidPtrType,
  //                                               Type::UIntTy, Type::UIntTy, 0));
  const Type * PoolDescTypePtr = PointerType::get(PoolDescType);
#endif

  std::vector<const Type *> Arg(1, VoidPtrType);
  Arg.push_back(VoidPtrType);
  FunctionType *PoolCheckTy =
    FunctionType::get(Type::VoidTy,Arg, false);
  PoolCheck = M.getOrInsertFunction("poolcheck", PoolCheckTy);

  std::vector<const Type *> Arg2(1, VoidPtrType);
  Arg2.push_back(VoidPtrType);
  Arg2.push_back(VoidPtrType);
  FunctionType *PoolCheckArrayTy =
    FunctionType::get(Type::VoidTy,Arg2, false);
  PoolCheckArray = M.getOrInsertFunction("poolcheckarray", PoolCheckArrayTy);
  PoolCheckIArray = M.getOrInsertFunction("poolcheckarray_i", PoolCheckArrayTy);


  std::vector<const Type *> Arg3(1, VoidPtrType);
  Arg3.push_back(VoidPtrType); //for output
  Arg3.push_back(VoidPtrType); //for referent 
  FunctionType *BoundsCheckTy = FunctionType::get(VoidPtrType,Arg3, false);
  BoundsCheck   = M.getOrInsertFunction("pchk_bounds", BoundsCheckTy);
  UIBoundsCheck = M.getOrInsertFunction("pchk_bounds_i", BoundsCheckTy);

  std::vector<const Type *> Arg4(1, VoidPtrType);
  Arg4.push_back(VoidPtrType);
  FunctionType *getBoundsTy = FunctionType::get(VoidPtrType,Arg4, false);
  getBounds   = M.getOrInsertFunction("getBounds",   getBoundsTy);
  UIgetBounds = M.getOrInsertFunction("getBounds_i", getBoundsTy);

  //Get the poolregister function
  PoolRegister = M.getOrInsertFunction("pchk_reg_obj", Type::VoidTy, VoidPtrType,
                                       VoidPtrType, Type::UIntTy, NULL);
  StackRegister = M.getOrInsertFunction("pchk_reg_stack", Type::VoidTy, VoidPtrType,
                                       VoidPtrType, Type::UIntTy, NULL);
  ObjFree = M.getOrInsertFunction("pchk_drop_obj", Type::VoidTy, VoidPtrType,
                                  VoidPtrType, NULL);
  StackFree = M.getOrInsertFunction("pchk_drop_stack", Type::VoidTy, VoidPtrType,
                                  VoidPtrType, NULL);
  
  FuncRegister = M.getOrInsertFunction("pchk_reg_func", Type::VoidTy, VoidPtrType, Type::UIntTy, PointerType::get(VoidPtrType), NULL);

  PoolFindMP = M.getOrInsertFunction("pchk_getLoc", VoidPtrType, VoidPtrType, NULL);
  PoolRegMP = M.getOrInsertFunction("pchk_reg_pool", Type::VoidTy, VoidPtrType, VoidPtrType, VoidPtrType, NULL);

  std::vector<const Type *> FArg2(1, Type::IntTy);
  FArg2.push_back(Type::IntTy);
  FArg2.push_back(VoidPtrType);
  FunctionType *ExactCheckTy = FunctionType::get(VoidPtrType, FArg2, false);
  ExactCheck = M.getOrInsertFunction("exactcheck", ExactCheckTy);

  std::vector<const Type *> FArg3(1, Type::UIntTy);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FunctionType *FunctionCheckTy = FunctionType::get(Type::VoidTy, FArg3, true);
  FunctionCheck = M.getOrInsertFunction("funccheck", FunctionCheckTy);

  std::vector<const Type *> FArg6(1, VoidPtrType);
  FArg6.push_back(VoidPtrType);
  FunctionType *FunctionCheckGTy = FunctionType::get(Type::VoidTy, FArg6, true);
  FunctionCheckG = M.getOrInsertFunction("funccheck_g", FunctionCheckGTy);

  std::vector<const Type *> FArg9(1, Type::UIntTy);
  FArg9.push_back(VoidPtrType);
  FArg9.push_back(PointerType::get(VoidPtrType));
  FunctionType *FunctionCheckTTy = FunctionType::get(Type::VoidTy, FArg9, true);
  FunctionCheckT = M.getOrInsertFunction("funccheck_t", FunctionCheckTTy);

  FArg9.clear();
  FArg9.push_back(VoidPtrType);
  FunctionType *ICCheckTy = FunctionType::get(Type::VoidTy, FArg9, true);
  ICCheck = M.getOrInsertFunction("pchk_iccheck", ICCheckTy);

  std::vector<const Type*> FArg5(1, VoidPtrType);
  FArg5.push_back(VoidPtrType);
  FunctionType *GetActualValueTy = FunctionType::get(VoidPtrType, FArg5, false);
  GetActualValue = M.getOrInsertFunction("pchk_getActualValue", GetActualValueTy);

  std::vector<const Type*> FArg4(1, VoidPtrType); //base
  FArg4.push_back(VoidPtrType); //result
  FArg4.push_back(Type::UIntTy); //size
  FunctionType *ExactCheck2Ty = FunctionType::get(VoidPtrType, FArg4, false);
  ExactCheck2  = M.getOrInsertFunction("exactcheck2",  ExactCheck2Ty);

  std::vector<const Type*> FArg7(1, VoidPtrType); //base
  FArg7.push_back(VoidPtrType); //result
  FArg7.push_back(VoidPtrType); //end
  FunctionType *ExactCheck3Ty = FunctionType::get(VoidPtrType, FArg7, false);
  ExactCheck3 = M.getOrInsertFunction("exactcheck3", ExactCheck3Ty);

  std::vector<const Type*> FArg8(1, VoidPtrType); //base
  FunctionType *getBeginEndTy = FunctionType::get(VoidPtrType, FArg8, false);
  getBegin = M.getOrInsertFunction("getBegin", getBeginEndTy);
  getEnd   = M.getOrInsertFunction("getEnd",   getBeginEndTy);
}

void
PreInsertPoolChecks::registerGlobalArraysWithGlobalPools(Module &M) {
#ifdef LLVA_KERNEL

  const Type *VoidPtrType = PointerType::get(Type::SByteTy); 
  const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
  const Type *PoolDescPtrTy = PointerType::get(PoolDescType);
  const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);

  //Get the registration function
  std::vector<const Type*> Vt;
  const FunctionType* RFT = FunctionType::get(Type::VoidTy, Vt, false);
  Function* RegFunc = M.getOrInsertFunction("poolcheckglobals", RFT);
  if (RegFunc->empty()) {
    BasicBlock* BB = new BasicBlock("reg", RegFunc);
    new ReturnInst(BB);
  }

  //Now iterate over globals and register all the arrays
  DSGraph &G = TDPass->getGlobalsGraph();
  Module::global_iterator GI = M.global_begin(), GE = M.global_end();
  for ( ; GI != GE; ++GI) {
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GI)) {
      if (GV->getType() != PoolDescPtrTy) {
        GlobalValue * GVLeader = G.getScalarMap().getLeaderForGlobal(GV);
        DSNode *DSN  = G.getNodeForValue(GVLeader).getNode();
        if (((isa<ArrayType>(GV->getType()->getElementType())) ||
            (DSN && DSN->isNodeCompletelyFolded()))
            && !isa<OpaqueType>(GV->getType())
            && !(isa<PointerType>(GV->getType()) && 
                 isa<OpaqueType>(cast<PointerType>(GV->getType())->getElementType()))) {
          Value * AllocSize;
          if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
            //std::cerr << "found global" << *GI << std::endl;
            AllocSize = ConstantInt::get(csiType,
                  (AT->getNumElements() * TD->getTypeSize(AT->getElementType())));
          } else {
            AllocSize = ConstantInt::get(csiType, TD->getTypeSize(GV->getType()->getElementType()));
          }
          Value* PH = getPD(DSN, M);
          if (PH)
            AddCallToRegFunc(RegFunc, GV, PoolRegister, PH, AllocSize);
        }
      }
    }
  }
#else
  Function *MainFunc = M.getMainFunction();
  if (MainFunc == 0 || MainFunc->isExternal()) {
    std::cerr << "Cannot do array bounds check for this program"
	      << "no 'main' function yet!\n";
    abort();
  }
  //First register, argc and argv
  Function::arg_iterator AI = MainFunc->arg_begin(), AE = MainFunc->arg_end();
  if (AI != AE) {
    //There is argc and argv
    Value *Argc = AI;
    AI++;
    Value *Argv = AI;
    PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*MainFunc);
    Value *PH= getPoolHandle(Argv, MainFunc, *FI);
    Function *PoolRegister = paPass->PoolRegister;
    BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin();
    while ((isa<CallInst>(InsertPt)) || isa<CastInst>(InsertPt) || isa<AllocaInst>(InsertPt) || isa<BinaryOperator>(InsertPt)) ++InsertPt;
    if (PH) {
      Type *VoidPtrType = PointerType::get(Type::SByteTy); 
      Instruction *GVCasted = new CastInst(Argv,
					   VoidPtrType, Argv->getName()+"casted",InsertPt);
      const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
      Value *AllocSize = new CastInst(Argc,
				      csiType, Argc->getName()+"casted",InsertPt);
      AllocSize = BinaryOperator::create(Instruction::Mul, AllocSize,
					 ConstantInt::get(csiType, 4), "sizetmp", InsertPt);
      new CallInst(PoolRegister,
				  make_vector(PH, AllocSize, GVCasted, 0),
				  "", InsertPt); 
      
    } else {
      std::cerr << "argv's pool descriptor is not present. \n";
      //	abort();
    }
    
  }

  //Now iterate over globals and register all the arrays
  Module::global_iterator GI = M.global_begin(), GE = M.global_end();
  for ( ; GI != GE; ++GI) {
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GI)) {
      Type *VoidPtrType = PointerType::get(Type::SByteTy); 
      Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
      Type *PoolDescPtrTy = PointerType::get(PoolDescType);
      if (GV->getType() != PoolDescPtrTy) {
        DSGraph &G = equivPass->getGlobalsGraph();
        DSNode *DSN  = G.getNodeForValue(GV).getNode();
        if ((isa<ArrayType>(GV->getType()->getElementType())) ||
            DSN->isNodeCompletelyFolded()) {
          Value * AllocSize;
          const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
          if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
            //std::cerr << "found global" << *GI << std::endl;
            AllocSize = ConstantInt::get(csiType,
                  (AT->getNumElements() * TD->getTypeSize(AT->getElementType())));
          } else {
            AllocSize = ConstantInt::get(csiType, TD->getTypeSize(GV->getType()));
          }
          Function *PoolRegister = paPass->PoolRegister;
          BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin();
          //skip the calls to poolinit
          while ((isa<CallInst>(InsertPt))  ||
                  isa<CastInst>(InsertPt)   ||
                  isa<AllocaInst>(InsertPt) ||
                  isa<BinaryOperator>(InsertPt)) ++InsertPt;
      
          std::map<const DSNode *, Value *>::iterator I = paPass->GlobalNodes.find(DSN);
          if (I != paPass->GlobalNodes.end()) {
            Value *PH = I->second;
            Instruction *GVCasted = new CastInst(GV,
                   VoidPtrType, GV->getName()+"casted",InsertPt);
            new CallInst(PoolRegister,
                make_vector(PH, AllocSize, GVCasted, 0),
                "", InsertPt); 
          } else {
            std::cerr << "pool descriptor not present \n ";
            abort();
          }
        }
      }
    }
  }
#endif
}

////////////////////////////////////////////////////////////////////////////
// Class: InsertPoolChecks
////////////////////////////////////////////////////////////////////////////

void
InsertPoolChecks::addPoolCheckProto(Module &M) {
  const Type * VoidPtrType = PointerType::get(Type::SByteTy);
#if 0
  const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
  //	StructType::get(make_vector<const Type*>(VoidPtrType, VoidPtrType,
  //                                               Type::UIntTy, Type::UIntTy, 0));
  const Type * PoolDescTypePtr = PointerType::get(PoolDescType);
#endif

  std::vector<const Type *> Arg(1, VoidPtrType);
  Arg.push_back(VoidPtrType);
  FunctionType *PoolCheckTy =
    FunctionType::get(Type::VoidTy,Arg, false);
  PoolCheck   = M.getOrInsertFunction("poolcheck", PoolCheckTy);
  PoolCheckUI = M.getOrInsertFunction("poolcheck_i", PoolCheckTy);

  Arg.clear();
  Arg.push_back(VoidPtrType);
  Arg.push_back(VoidPtrType);
  Arg.push_back(Type::UIntTy);
  PoolCheckTy = FunctionType::get(Type::VoidTy,Arg, false);
  PoolCheckAlign   = M.getOrInsertFunction("poolcheckalign", PoolCheckTy);
  PoolCheckAlignUI = M.getOrInsertFunction("poolcheckalign_i", PoolCheckTy);

  std::vector<const Type *> Arg2(1, VoidPtrType);
  Arg2.push_back(VoidPtrType);
  Arg2.push_back(VoidPtrType);
  FunctionType *PoolCheckArrayTy =
    FunctionType::get(Type::VoidTy,Arg2, false);
  PoolCheckArray = M.getOrInsertFunction("poolcheckarray", PoolCheckArrayTy);
  PoolCheckIArray = M.getOrInsertFunction("poolcheckarray_i", PoolCheckArrayTy);


  std::vector<const Type *> Arg3(1, VoidPtrType);
  Arg3.push_back(VoidPtrType); //for output
  Arg3.push_back(VoidPtrType); //for referent 
  FunctionType *BoundsCheckTy = FunctionType::get(VoidPtrType,Arg3, false);
  BoundsCheck   = M.getOrInsertFunction("pchk_bounds", BoundsCheckTy);
  UIBoundsCheck = M.getOrInsertFunction("pchk_bounds_i", BoundsCheckTy);

  std::vector<const Type *> Arg4(1, VoidPtrType);
  Arg4.push_back(VoidPtrType);
  FunctionType *getBoundsTy = FunctionType::get(VoidPtrType,Arg4, false);
  getBounds   = M.getOrInsertFunction("getBounds",   getBoundsTy);
  UIgetBounds = M.getOrInsertFunction("getBounds_i", getBoundsTy);

  //Get the poolregister function
  PoolRegister = M.getOrInsertFunction("pchk_reg_obj", Type::VoidTy, VoidPtrType,
                                       VoidPtrType, Type::UIntTy, NULL);
  StackRegister = M.getOrInsertFunction("pchk_reg_stack", Type::VoidTy, VoidPtrType,
                                       VoidPtrType, Type::UIntTy, NULL);
  ObjFree = M.getOrInsertFunction("pchk_drop_obj", Type::VoidTy, VoidPtrType,
                                  VoidPtrType, NULL);
  StackFree = M.getOrInsertFunction("pchk_drop_stack", Type::VoidTy, VoidPtrType,
                                  VoidPtrType, NULL);
  
  FuncRegister = M.getOrInsertFunction("pchk_reg_func", Type::VoidTy, VoidPtrType, Type::UIntTy, PointerType::get(VoidPtrType), NULL);

  PoolFindMP = M.getOrInsertFunction("pchk_getLoc", VoidPtrType, VoidPtrType, NULL);
  PoolRegMP = M.getOrInsertFunction("pchk_reg_pool", Type::VoidTy, VoidPtrType, VoidPtrType, VoidPtrType, NULL);

  //  Function *KmemCacheAlloc = M.getNamedFunction("kmem_cache_alloc");
  //  assert(KmemCacheAlloc->arg_size() == 2 &&"Kmem_cache_alloc number of arguments != 2");
  //  Function::arg_iterator kcai = KmemCacheAlloc->arg_begin();
  //  Type *kmem_cache_t = kcai->getType();
  //  kcai++;
  //  Type *kem_cache_size_t = kcai->getType();
  //  We'll use Void * instead of the above
  KmemCachegetSize = M.getOrInsertFunction("kmem_cache_size", Type::UIntTy, VoidPtrType, NULL);

  std::vector<const Type *> FArg2(1, Type::IntTy);
  FArg2.push_back(Type::IntTy);
  FArg2.push_back(VoidPtrType);
  FunctionType *ExactCheckTy = FunctionType::get(VoidPtrType, FArg2, false);
  ExactCheck = M.getOrInsertFunction("exactcheck", ExactCheckTy);

  std::vector<const Type *> FArg3(1, Type::UIntTy);
  FArg3.push_back(VoidPtrType);
  FArg3.push_back(VoidPtrType);
  FunctionType *FunctionCheckTy = FunctionType::get(Type::VoidTy, FArg3, true);
  FunctionCheck = M.getOrInsertFunction("funccheck", FunctionCheckTy);

  std::vector<const Type *> FArg6(1, VoidPtrType);
  FArg6.push_back(VoidPtrType);
  FunctionType *FunctionCheckGTy = FunctionType::get(Type::VoidTy, FArg6, true);
  FunctionCheckG = M.getOrInsertFunction("funccheck_g", FunctionCheckGTy);

  std::vector<const Type *> FArg9(1, Type::UIntTy);
  FArg9.push_back(VoidPtrType);
  FArg9.push_back(PointerType::get(VoidPtrType));
  FunctionType *FunctionCheckTTy = FunctionType::get(Type::VoidTy, FArg9, true);
  FunctionCheckT = M.getOrInsertFunction("funccheck_t", FunctionCheckTTy);

  FArg9.clear();
  FArg9.push_back(VoidPtrType);
  FunctionType *ICCheckTy = FunctionType::get(Type::VoidTy, FArg9, true);
  ICCheck = M.getOrInsertFunction("pchk_iccheck", ICCheckTy);

  std::vector<const Type*> FArg5(1, VoidPtrType);
  FArg5.push_back(VoidPtrType);
  FunctionType *GetActualValueTy = FunctionType::get(VoidPtrType, FArg5, false);
  GetActualValue = M.getOrInsertFunction("pchk_getActualValue", GetActualValueTy);

  std::vector<const Type*> FArg4(1, VoidPtrType); //base
  FArg4.push_back(VoidPtrType); //result
  FArg4.push_back(Type::UIntTy); //size
  FunctionType *ExactCheck2Ty = FunctionType::get(VoidPtrType, FArg4, false);
  ExactCheck2  = M.getOrInsertFunction("exactcheck2",  ExactCheck2Ty);

  std::vector<const Type*> FArg7(1, VoidPtrType); //base
  FArg7.push_back(VoidPtrType); //result
  FArg7.push_back(VoidPtrType); //end
  FunctionType *ExactCheck3Ty = FunctionType::get(VoidPtrType, FArg7, false);
  ExactCheck3 = M.getOrInsertFunction("exactcheck3", ExactCheck3Ty);

  std::vector<const Type*> FArg8(1, VoidPtrType); //base
  FunctionType *getBeginEndTy = FunctionType::get(VoidPtrType, FArg8, false);
  getBegin = M.getOrInsertFunction("getBegin", getBeginEndTy);
  getEnd   = M.getOrInsertFunction("getEnd",   getBeginEndTy);
}


void
InsertPoolChecks::addHeapRegs (Module & M) {
  DSNode * Node;
  MetaPool * MP;
  const Type * VoidPtrType = PointerType::get(Type::SByteTy);
  std::set<Value *> ProcessedMetaPools;
  std::vector<Value *> args;

  while (PHNeeded.size()) {
    Node = *(PHNeeded.begin());
    PHNeeded.erase(Node);
    MP = Node->getMP();
    Value* MPV = MP->getMetaPoolValue();

    //
    // Determine if we have already processed this MetaPool.  If we have, then
    // just go on to the next DSNode.
    if (ProcessedMetaPools.find (MPV) == ProcessedMetaPools.end())
      ProcessedMetaPools.insert (MPV);
    else
      continue;

    // Add registers in front of every allocation
    for (std::list<CallSite>::iterator i = MP->allocs.begin(),
          e = MP->allocs.end(); i != e; ++i) {
      args.clear();
      std::string name = i->getCalledFunction()->getName();
      if (name == "kmem_cache_alloc") {
        Instruction * InsertPt = i->getInstruction();
        //insert a register before
        Value* VP  = castTo (i->getArgument(0), VoidPtrType, InsertPt);
        Value* VMP = castTo (MPV, VoidPtrType, InsertPt);
        Value* VMPP = new CallInst(PoolFindMP, VP, "", InsertPt);

        args.push_back (VMP);
        args.push_back (VP);
        args.push_back (VMPP);
        new CallInst (PoolRegMP, args, "", i->getInstruction());

        //Insert Obj reg using kmem_cache_size after
        Instruction* IP = i->getInstruction()->getNext();
        Value* VRP = castTo (i->getInstruction(), VoidPtrType, IP);
        CallInst *len = new CallInst(KmemCachegetSize, VP, "", IP);

        args.clear();
        args.push_back (VMP); //MetaPool
        args.push_back (VRP); //object 
        args.push_back (len); //len
        new CallInst(PoolRegister, args, "", IP);

#if 0
      } else if ((name == "kmalloc") ||
#else
      } else if (
#endif
                 (name == "__vmalloc") ||
                 (name == "__alloc_bootmem")) {
        //inser obj register after
        Instruction* IP = i->getInstruction()->getNext();
        Value* VP = castTo (i->getInstruction(), VoidPtrType, IP);
        Value* VMP = castTo (MPV, VoidPtrType, IP);
        Value* len = castTo (i->getArgument(0), Type::UIntTy, IP);

        args.push_back (VMP);
        args.push_back (VP);
        args.push_back (len);
        new CallInst(PoolRegister, args, "", IP);
      } else
        assert(0 && "unknown alloc");
    }
  }
}

void InsertPoolChecks::addMetaPools(Module& M, MetaPool* MP, DSNode* N) {
  if (!MP || MP->getMetaPoolValue()) return;
  MP->setMetaPoolValue(makeMetaPool(&M, N));  
  Value* MPV = MP->getMetaPoolValue();
  //added registers in front of every allocation
  for(std::list<CallSite>::iterator i = MP->allocs.begin(),
        e = MP->allocs.end(); i != e; ++i) {
    std::string name = i->getCalledFunction()->getName();
    if (name == "kmem_cache_alloc") {
      //insert a register before
      Value* VP = new CastInst(i->getArgument(0), PointerType::get(Type::SByteTy), "", i->getInstruction());
      Value* VMP = new CastInst(MPV, PointerType::get(Type::SByteTy), "MP", i->getInstruction());
      Value* VMPP = new CallInst(PoolFindMP, make_vector(VP, 0), "", i->getInstruction());
      new CallInst(PoolRegMP, make_vector(VMP, VP, VMPP, 0), "", i->getInstruction());
#if 0
    } else if ((name == "kmalloc") ||
#else
    } else if (
#endif
               (name == "__vmalloc") ||
               (name == "__alloc_bootmem")) {
      //inser obj register after
      Instruction* IP = i->getInstruction()->getNext();
      Value* VP = new CastInst(i->getInstruction(), PointerType::get(Type::SByteTy), "", IP);
      Value* VMP = new CastInst(MPV, PointerType::get(Type::SByteTy), "MP", IP);
      Value* len = new CastInst(i->getArgument(0), Type::UIntTy, "len", IP);
      new CallInst(PoolRegister, make_vector(VMP, VP, len, 0), "", IP);
    } else
      assert(0 && "unknown alloc");
  }
}

void InsertPoolChecks::addObjFrees(Module& M) {
#ifdef LLVA_KERNEL
#if 0
  Function* KMF = M.getNamedFunction("kfree");
#endif
  Function* VMF = M.getNamedFunction("vfree");
  std::list<Function*> L;
#if 0
  if (KMF) L.push_back(KMF);
#endif
  if (VMF) L.push_back(VMF);
  for (std::list<Function*>::iterator ii = L.begin(), ee = L.end();
       ii != ee; ++ii) {
    Function* F = *ii;
    for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
         ii != ee; ++ii) {
      if (CallInst* CI = dyn_cast<CallInst>(*ii)) {
        if (CI->getCalledFunction() == F) {
          Value* Ptr = CI->getOperand(1);
          Value* MP = getPD(getDSNode(Ptr, CI->getParent()->getParent()), M);
          if (MP) {
            MP = new CastInst(MP, PointerType::get(Type::SByteTy), "MP", CI);
            Ptr = new CastInst(Ptr, PointerType::get(Type::SByteTy), "ADDR", CI);
            new CallInst(ObjFree, make_vector(MP, Ptr, 0), "", CI);
          }
        }
      }
    }
  }
#endif
}

//
// Method: insertICCheck()
//
// Description:
//  Perform a run-time check to ensure that this pointer points to the
//  beginning of an interrupt context.
//
void
InsertPoolChecks::insertICCheck (Value * IC, Instruction * InsertPt) {
  const Type * VoidPtrType = PointerType::get(Type::SByteTy);
  Value * CastPointer = castTo (IC, VoidPtrType, InsertPt);
  new CallInst (ICCheck, CastPointer, "", InsertPt);
}

//
// Return value:
//  Returns the inserted boundscheck call instruction.  This can be used to
//  replace the destination instruction if desired.
//  If no instruction was inserted, it returns Dest.
//
Value *
InsertPoolChecks::insertBoundsCheck (Instruction * I,
                                     Value * Src,
                                     Value * Dest,
                                     Instruction * InsertPt) {
  // Enclosing function
  Function * F   = I->getParent()->getParent();
  Function *Fnew = F;

  // Source node on which we will look up the pool handle
  Value *newSrc = Src;

#ifndef LLVA_KERNEL    
  // Some times the ECGraphs doesnt contain F for newly created cloned
  // functions
  if (!equivPass->ContainsDSGraphFor(*F)) {
    PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
    newSrc = FI->MapValueToOriginal(MAI);
    assert(newSrc && " Instruction not in value map (clone)\n");
  }
  Function *Fnew = newSrc->getParent()->getParent();
#endif          

  //
  // Get the pool handle for the source pointer.
  //
  Value *PH = getPoolHandle(newSrc, Fnew); 
  if (!PH) {
    // Update statistics
    ++NullBoundsChecks;
    return Dest;
  }

  //
  // Get the DSGraph of the enclosing function and get the corresponding
  // DSNode.
  //
  DSGraph & TDG = TDPass->getDSGraph(*F);
  DSNode * Node = TDG.getNodeForValue(I).getNode();

  //
  // Determine whether an alignment check is needed.  This occurs when a DSNode
  // is type unknown (collapsed) but has pointers to type known (uncollapsed)
  // DSNodes.
  //
  if (preSCPass->nodeNeedsAlignment (Node)) {
    ++AlignChecks;
  }

  // If there is no DSNode, do not perform a check
  if (!Node) return Dest;

  // Record statistics on the incomplete checks we do.  Note that a node may
  // be counted more than once.
  if (Node->isIncomplete())
    ++IBoundsChecks;
  if (Node->isUnknownNode())
    ++UBoundsChecks;
  if (Node->isAllocaNode())
    ++ABoundsChecks;

  //
  // Cast the pool handle, source and destination pointers into the correct
  // type for the call instruction.
  //
  Value * SrcCast = Src;
  Value * DestCast = Dest;
  if (Src->getType() != PointerType::get(Type::SByteTy))
    SrcCast = new CastInst (Src, PointerType::get(Type::SByteTy),
                            "castsrc", InsertPt);
  if (Dest->getType() != PointerType::get(Type::SByteTy))
    DestCast = new CastInst (Dest, PointerType::get(Type::SByteTy),
                            "castdst", InsertPt);
  if (PH->getType() != PointerType::get(Type::SByteTy))
    PH = new CastInst (PH, PointerType::get(Type::SByteTy),
                            "castph", InsertPt);

  AddedValues.insert(DestCast);

  //
  // Insert the bounds check.
  //
  Value * CI;
  if (EnableSplitChecks) {
    std::vector<Value *> args(1, PH);
    args.push_back (SrcCast);
    if ((Node == 0) ||
        (Node->isAllocaNode()) ||
        (Node->isIncomplete()) ||
        (Node->isUnknownNode()))
      CI = new CallInst(UIgetBounds, args, "uibc",InsertPt);
    else
      CI = new CallInst(getBounds, args, "bc", InsertPt);
    std::vector<Value *> boundsargs(1, CI);
    Instruction * LowerBound = new CallInst(getBegin, boundsargs, "gb", InsertPt);
    Instruction * UpperBound = new CallInst(getEnd,   boundsargs, "ge", InsertPt);
    Value * EC3 = addExactCheck3 (LowerBound, DestCast, UpperBound, InsertPt);
    AddedValues.insert(EC3);
    if (EC3->getType() != Dest->getType())
      EC3 = new CastInst(EC3, Dest->getType(), EC3->getName(), InsertPt);
    AddedValues.insert(EC3);
    // Replace all uses of the original pointer with the result of the exactcheck.
    // This ensures that the check will not get dead code eliminated.
    Value::use_iterator UI = Dest->use_begin();
    for (; UI != Dest->use_end(); ++UI) {
      if (AddedValues.find(*UI) == AddedValues.end())
        UI->replaceUsesOfWith (Dest,EC3);
    }
    CI = EC3;
  } else {
    std::vector<Value *> args(1, PH);
    args.push_back (SrcCast);
    args.push_back (DestCast);
    if ((Node == 0) ||
        (Node->isAllocaNode()) ||
        (Node->isIncomplete()) ||
        (Node->isUnknownNode()))
      CI = new CallInst(UIBoundsCheck, args, "uibc",InsertPt);
    else
      CI = new CallInst(BoundsCheck, args, "bc", InsertPt);
  }

  //
  // Record that this value was checked.
  //
  CheckedValues.insert (Dest);
  CheckedValues.insert (CI);

  // Update statistics
  ++BoundsChecks;
  return CI;
}

//
// Method: getOrCreateFunctionTable()
//
// Description:
//  Given a DSNode, return a global variable containing an array of the
//  function pointers within that DSNode.  If this global variable does not
//  exist, create it and modify poolcheckglobals() to register it with its
//  MetaPool.
//
GlobalVariable *
InsertPoolChecks::getOrCreateFunctionTable (DSNode * Node, Value * PH,
                                            Module * M) {
  // Determine if we have already created such a global.
  if (FuncListMap.count (PH)) {
    return FuncListMap[PH];
  }

	// Get the globals list corresponding to the node
	std::vector<Function *> FuncList;
	Node->addFullFunctionList(FuncList);
	unsigned num = FuncList.size();

  // Create a global array of void pointers containing the list of possible
  // function targets.
  std::vector<Function *>::iterator flI= FuncList.begin(), flE = FuncList.end();
  const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
  Value *NumArg = ConstantInt::get(csiType, num);	
  Type *VoidPtrType = PointerType::get(Type::SByteTy); 
  std::vector<Constant *> Targets;

  for (; flI != flE ; ++flI) {
    Function *func = *flI;
    Constant *CastfuncI = ConstantExpr::getCast (func, VoidPtrType);
    Targets.push_back(CastfuncI);
  }

  ArrayType * TableType = ArrayType::get (VoidPtrType, num);
  Constant * TableInit = ConstantArray::get (TableType, Targets);
  GlobalVariable * Table = new GlobalVariable (TableType, true, GlobalValue::InternalLinkage, TableInit, "functargets", M);
  Value * TableCast = ConstantExpr::getCast (Table, PointerType::get(VoidPtrType));

  //
  // Add an instruction to poolcheckglobals() to register this table of
  // functions with the MetaPool.
  //
  std::vector<const Type*> Vt;
  const FunctionType* RFT = FunctionType::get(Type::VoidTy, Vt, false);
  Function * RegFunc = M->getOrInsertFunction("poolcheckglobals", RFT);
  BasicBlock* BB;
  if (RegFunc->empty()) {
    BasicBlock* BB = new BasicBlock("reg", RegFunc);
    new ReturnInst(BB);
  } else {
    BB = &(RegFunc->getEntryBlock());
  }

  Instruction * InsertPt = BB->getTerminator();
  Value * CastPH = new CastInst(PH, VoidPtrType, "casted", InsertPt);
  std::vector<Value *> args;
  args.push_back (CastPH);
  args.push_back (NumArg);
  args.push_back (TableCast);
  new CallInst(FuncRegister, args, "", InsertPt); 

  //
  // Insert the DSNode and Table into the map.
  //
  FuncListMap.insert (make_pair(PH,Table));
  return Table;
}

//
// Method: insertFunctionCheck()
//
// Description:
//  Insert a run-time check on the argument to an indirect call instruction.
//
void
InsertPoolChecks::insertFunctionCheck (CallInst * CI) {
  if (DisableFuncChecks)
    return;

  // Get the containing function and the function pointer.
  Function * F = CI->getParent()->getParent();
  Value * FuncPointer = CI->getCalledValue();

  // Try to remove any encapsulating casts to get to the original instruction
  ConstantExpr *cExpr;
  while ((cExpr = dyn_cast<ConstantExpr>(FuncPointer)) &&
         (cExpr->getOpcode() == Instruction::Cast))
      FuncPointer = cExpr->getOperand(0);

  //
  // Determine if the function pointer came from a load instruction that loaded
  // its value from a type known pool.  If it is, it does not need a check.
  //
  if (LoadInst * LI = dyn_cast<LoadInst>(FuncPointer)) {
    DSNode * LoadNode = getDSNode (LI->getPointerOperand(), F);
    if ((LoadNode) && (!(LoadNode->isNodeCompletelyFolded())))
      return;
  }

  //
  // Get the DSNode and Pool handle for the call instruction.
  //
  Value *PH = getPoolHandle (FuncPointer, F);
  if (!PH) {
    // Update statistics
    ++NullBoundsChecks;
    return;
  }
  DSNode* Node = getDSNode(FuncPointer, F);

  //
  // If the node is incomplete, then the call targets associated with the
  // DSNode may be missing valid function targets.  In that case, do not
  // insert a check.
  //
  if ((!EnableUnknownChecks) && (Node->isIncomplete())) {
    ++MissedFuncChecks;
    return;
  }
 
	// Get the globals list corresponding to the node
	std::vector<Function *> FuncList;
	Node->addFullFunctionList(FuncList);
	unsigned num = FuncList.size();

  //
  // Insert a call to one of the function check functions, depending upon
  // the number of functions we must check against.
  //
  if (num == 0) {
    ++ZeroFuncChecks;
    return;
  }

  // Update statistics on the number of indirect call checks.
  ++FuncChecks;

  std::vector<Function *>::iterator flI= FuncList.begin(), flE = FuncList.end();
  const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
  Value *NumArg = ConstantInt::get(csiType, num);	
  Type *VoidPtrType = PointerType::get(Type::SByteTy); 

  if (num < 7) {
    const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
    Value *NumArg = ConstantInt::get(csiType, num);	
           
    CastInst *CastVI = 
      new CastInst(FuncPointer, VoidPtrType, "casted", (Instruction *)(CI));
  
    std::vector<Value *> args(1, NumArg);
    args.push_back(CastVI);
    for (; flI != flE ; ++flI) {
      Function *func = *flI;
      CastInst *CastfuncI = 
        new CastInst(func, VoidPtrType, "casted", (Instruction *)(CI));
      args.push_back(CastfuncI);
    }
    for (unsigned index = num; index < 7; ++index)
      args.push_back (ConstantPointerNull::get (PointerType::get (Type::SByteTy)));
    new CallInst(FunctionCheck, args,"", (Instruction *)(CI));
  } else if (num < 21) {
    // Create the first two arguments for the function check call
    std::vector<Value *> args(1, NumArg);
    CastInst *CastVI = 
      new CastInst(FuncPointer, VoidPtrType, "casted", (Instruction *)(CI));
    args.push_back(CastVI);

    // Create a global array of void pointers containing the list of possible
    // function targets.
    GlobalVariable * Table = getOrCreateFunctionTable (Node, PH, F->getParent());

    CastInst *CastTable = 
      new CastInst(Table, 
       PointerType::get(VoidPtrType), "casted", (Instruction *)(CI));
  
    args.push_back(CastTable);
    new CallInst(FunctionCheckT, args, "", (Instruction *)(CI));
  } else {
    // Create a global array of void pointers containing the list of possible
    // function targets.
    getOrCreateFunctionTable (Node, PH, F->getParent());

    // Create the first two arguments for the function check call
    PH = new CastInst (PH, VoidPtrType, "casted", (Instruction *)(CI));
    CastInst *CastVI = 
      new CastInst(FuncPointer, VoidPtrType, "casted", (Instruction *)(CI));
    std::vector<Value *> args(1, PH);
    args.push_back(CastVI);

    new CallInst(FunctionCheckG, args,"", (Instruction *)(CI));
  }
}

//
// Function: addExactCheck2()
//
// Description:
//  Utility routine that inserts a call to exactcheck2().
//
// Inputs:
//  BasePointer   - An LLVM Value representing the base of the object to check.
//  Result        - An LLVM Value representing the pointer to check.
//  Bounds        - An LLVM Value representing the bounds of the check.
//  InsertPt      - The instruction before which to insert the check.
//
void
InsertPoolChecks::addExactCheck2 (Value * BasePointer,
                                  Value * Result,
                                  Value * Bounds,
                                  Instruction * InsertPt) {
  Value * ResultPointer = Result;

  // The LLVM type for a void *
  Type *VoidPtrType = PointerType::get(Type::SByteTy); 

  //
  // Cast the operands to the correct type.
  //
  if (BasePointer->getType() != VoidPtrType)
    BasePointer = new CastInst(BasePointer, VoidPtrType,
                               BasePointer->getName()+".ec2.casted",
                               InsertPt);

  if (ResultPointer->getType() != VoidPtrType)
    ResultPointer = new CastInst(ResultPointer, VoidPtrType,
                                 ResultPointer->getName()+".ec2.casted",
                                 InsertPt);

  Value * CastBounds = Bounds;
  if (Bounds->getType() != Type::UIntTy)
    CastBounds = new CastInst(Bounds, Type::UIntTy,
                              Bounds->getName()+".ec.casted", InsertPt);

  //
  // Create the call to exactcheck2().
  //
  std::vector<Value *> args(1, BasePointer);
  args.push_back(ResultPointer);
  args.push_back(CastBounds);
  Instruction * CI;
  CI = new CallInst(ExactCheck2, args, "", InsertPt);

  //
  // Record that this value was checked.
  //
  CheckedValues.insert (Result);

#if 0
  //
  // Replace the old pointer with the return value of exactcheck2(); this
  // prevents GCC from removing it completely.
  //
  if (CI->getType() != GEP->getType())
    CI = new CastInst (CI, GEP->getType(), GEP->getName(), InsertPt);

  Value::use_iterator UI = GEP->use_begin();
  for (; UI != GEP->use_end(); ++UI) {
    if (((*UI) != CI) && ((*UI) != ResultPointer))
      UI->replaceUsesOfWith (GEP, CI);
  }
#endif

  // Update statistics
  ++ExactChecks;
  return;
}

//
// Function: addExactCheck3()
//
// Description:
//  Utility routine that inserts a call to exactcheck3().
//
// Inputs:
//  Source   - The pointer that is the lower bound of the array.
//  Result   - The pointer that we wish to check.
//  Bounds   - The length of the array in bytes.
//  InsertPt - The instruction before which to insert the check.
//
Value *
InsertPoolChecks::addExactCheck3 (Value * Source,
                                  Value * Result,
                                  Value * Bounds,
                                  Instruction * InsertPt) {
  // The LLVM type for a void *
  Type *VoidPtrType = PointerType::get(Type::SByteTy); 

  // Update statistics
  ++ExactChecks;

  //
  // Cast the operands to the correct type.
  //
  Value * BasePointer = Source;
  if (BasePointer->getType() != VoidPtrType)
    BasePointer = new CastInst(BasePointer, VoidPtrType,
                               BasePointer->getName()+".ec3.base.casted",
                               InsertPt);

  Value * ResultPointer = Result;
  if (ResultPointer->getType() != VoidPtrType)
    ResultPointer = new CastInst(Result, VoidPtrType,
                                 Result->getName()+".ec3.result.casted",
                                 InsertPt);

  Value * CastBounds = Bounds;
  if (Bounds->getType() != VoidPtrType)
    CastBounds = new CastInst(Bounds, VoidPtrType,
                              Bounds->getName()+".ec3.end.casted", InsertPt);

  std::vector<Value *> args(1, BasePointer);
  args.push_back(ResultPointer);
  args.push_back(CastBounds);

  //
  // Record that this value was checked.
  //
  CheckedValues.insert (Result);
  return new CallInst(ExactCheck3, args, "ec3", InsertPt);
}

//
// Function: addExactCheck()
//
// Description:
//  Utility routine that inserts a call to exactcheck().  This function can
//  perform some optimization be determining if the arguments are constant.
//  If they are, we can forego inserting the call.
//
// Inputs:
//  Index - An LLVM Value representing the index of the access.
//  Bounds - An LLVM Value representing the bounds of the check.
//
void
InsertPoolChecks::addExactCheck (Value * Pointer,
                                 Value * Index, Value * Bounds,
                                 Instruction * InsertPt) {
  //
  // Record that this value was checked.
  //
  CheckedValues.insert (Pointer);

  //
  // Attempt to determine statically if this check will always pass; if so,
  // then don't bother doing it at run-time.
  //
  ConstantInt * CIndex  = dyn_cast<ConstantInt>(Index);
  ConstantInt * CBounds = dyn_cast<ConstantInt>(Bounds);
  if (CIndex && CBounds) {
    int index  = CIndex->getSExtValue();
    int bounds = CBounds->getSExtValue();
    assert ((index >= 0) && "exactcheck: const negative index");
    assert ((index < bounds) && "exactcheck: const out of range");

    // Update stats and return
    ++ConstExactChecks;
    return;
  }

  //
  // Second, cast the operands to the correct type.
  //
  Value * CastIndex = Index;
  if (Index->getType() != Type::IntTy)
    CastIndex = new CastInst(Index, Type::IntTy,
                             Index->getName()+".ec.casted", InsertPt);

  Value * CastBounds = Bounds;
  if (Bounds->getType() != Type::IntTy)
    CastBounds = new CastInst(Bounds, Type::IntTy,
                              Bounds->getName()+".ec.casted", InsertPt);

  const Type *VoidPtrType = PointerType::get(Type::SByteTy); 
  Value * CastResult = Pointer;
  if (CastResult->getType() != VoidPtrType)
    CastResult = new CastInst(CastResult, VoidPtrType,
                              CastResult->getName()+".ec.casted", InsertPt);

  std::vector<Value *> args(1, CastIndex);
  args.push_back(CastBounds);
  args.push_back(CastResult);
  Instruction * CI = new CallInst(ExactCheck, args, "ec", InsertPt);

#if 0
  //
  // Replace the old index with the return value of exactcheck(); this
  // prevents GCC from removing it completely.
  //
  Value * CastCI = CI;
  if (CI->getType() != GEP->getType())
    CastCI = new CastInst (CI, GEP->getType(), GEP->getName(), InsertPt);

  Value::use_iterator UI = GEP->use_begin();
  for (; UI != GEP->use_end(); ++UI) {
    if (((*UI) != CI) && ((*UI) != CastResult))
      UI->replaceUsesOfWith (GEP, CastCI);
  }
#endif

  // Update statistics
  ++ExactChecks;
  return;
}

//
// Function: addExactCheck()
//
// Description:
//  Utility routine that inserts a call to exactcheck().  This function can
//  perform some optimization be determining if the arguments are constant.
//  If they are, we can forego inserting the call.
//
// Inputs:
//  GEP - The GEP for which the check will be done.
//  Index - An LLVM Value representing the index of the access.
//  Bounds - An LLVM Value representing the bounds of the check.
//
void
InsertPoolChecks::addExactCheck (Instruction * GEP,
                                 Value * Index, Value * Bounds) {
  //
  // Record that this value was checked.
  //
  CheckedValues.insert (GEP);

  // Upper and lower values on the index and bounds
  int index_lower;
  int index_upper;
  int bounds_lower;
  int bounds_upper;

  //
  // First, attempt to determine statically whether the check will always pass.
  // If so, then don't bother doing it at run-time.
  //
  ConstantInt * CIndex  = dyn_cast<ConstantInt>(Index);
  ConstantInt * CBounds = dyn_cast<ConstantInt>(Bounds);
  if (CIndex && CBounds) {
    int index  = CIndex->getSExtValue();
    int bounds = CBounds->getSExtValue();
    assert ((index >= 0) && "exactcheck: const negative index");
    assert ((index < bounds) && "exactcheck: const out of range");

    // Update stats and return
    ++ConstExactChecks;
    return;
  } else if (CBounds) {
    int bounds = CBounds->getSExtValue();
    SCEVHandle SCEVIndex  = scevPass->getSCEV (Index);
    ConstantRange IndexRange  = SCEVIndex->getValueRange();
    if (!(IndexRange.isWrappedSet())) {
      int index_lower = IndexRange.getLower()->getSExtValue();
      int index_upper = IndexRange.getUpper()->getSExtValue();
      int bounds_lower = bounds;
      int bounds_upper = bounds;

      if ((index_lower >= 0) && (index_upper < bounds_lower)) {
        ++ConstExactChecks;
        return;
      }
    }
  }

  SCEVHandle SCEVIndex  = scevPass->getSCEV (Index);
  SCEVHandle SCEVBounds = scevPass->getSCEV (Bounds);
  ConstantRange BoundsRange = SCEVBounds->getValueRange();
  ConstantRange IndexRange  = SCEVIndex->getValueRange();
  if ((!(IndexRange.isWrappedSet())) && (!(BoundsRange.isWrappedSet()))) {
    int index_lower = IndexRange.getLower()->getSExtValue();
    int index_upper = IndexRange.getUpper()->getSExtValue();
    int bounds_lower = BoundsRange.getLower()->getSExtValue();
    int bounds_upper = BoundsRange.getUpper()->getSExtValue();

    if ((index_lower >= 0) && (index_upper < bounds_lower)) {
      ++ConstExactChecks;
      return;
    }
  }

  //
  // Cast the operands to the correct type.
  //
  Instruction * InsertPt = GEP->getNext();

  Value * CastIndex = Index;
  if (Index->getType() != Type::IntTy)
    CastIndex = new CastInst(Index, Type::IntTy,
                             Index->getName()+".ec.casted", InsertPt);

  Value * CastBounds = Bounds;
  if (Bounds->getType() != Type::IntTy)
    CastBounds = new CastInst(Bounds, Type::IntTy,
                              Bounds->getName()+".ec.casted", InsertPt);

  const Type *VoidPtrType = PointerType::get(Type::SByteTy); 
  Value * CastResult = GEP;
  if (CastResult->getType() != VoidPtrType)
    CastResult = new CastInst(CastResult, VoidPtrType,
                              CastResult->getName()+".ec.casted", InsertPt);

  std::vector<Value *> args(1, CastIndex);
  args.push_back(CastBounds);
  args.push_back(CastResult);
  Instruction * CI = new CallInst(ExactCheck, args, "ec", InsertPt);

  //
  // Replace the old index with the return value of exactcheck(); this
  // prevents GCC from removing it completely.
  //
#if 0
  Value * CastCI = CI;
  if (CI->getType() != GEP->getType())
    CastCI = new CastInst (CI, GEP->getType(), GEP->getName(), InsertPt);

  Value::use_iterator UI = GEP->use_begin();
  for (; UI != GEP->use_end(); ++UI) {
    if (((*UI) != CI) && ((*UI) != CastResult))
      UI->replaceUsesOfWith (GEP, CastCI);
  }
#endif

  // Update statistics
  ++ExactChecks;
  return;
}

//
// Function: isEligableForExactCheck()
//
// Return value:
//  true  - This value is eligable for an exactcheck.
//  false - This value is not eligable for an exactcheck.
//
static inline bool
isEligableForExactCheck (Value * Pointer) {
  if ((isa<AllocaInst>(Pointer)) || (isa<GlobalVariable>(Pointer)))
    return true;

  if (CallInst* CI = dyn_cast<CallInst>(Pointer)) {
    if (CI->getCalledFunction() &&
        (CI->getCalledFunction()->getName() == "__vmalloc" || 
         CI->getCalledFunction()->getName() == "kmalloc")) {
      return true;
    }
  }

  return false;
}

//
// Function: findCheckedPointer()
//
// Description:
//  Given a pointer value, attempt to determine whether the pointer or all of
//  the instructions that created it have been checked.
//
bool
InsertPoolChecks::findCheckedPointer (Value * PointerOperand) {
  Value * SourcePointer = PointerOperand;

  while (CheckedValues.find (SourcePointer) == CheckedValues.end()) {
    // Check for cast constant expressions and instructions
    if (ConstantExpr * cExpr = dyn_cast<ConstantExpr>(SourcePointer)) {
      if (cExpr->getOpcode() == Instruction::Cast) {
        if (isa<PointerType>(cExpr->getOperand(0)->getType())) {
          SourcePointer = cExpr->getOperand(0);
          continue;
        }
      }
      // We cannot handle this expression; break out of the loop
      break;
    }

    if (CastInst * CastI = dyn_cast<CastInst>(SourcePointer)) {
      if (isa<PointerType>(CastI->getOperand(0)->getType())) {
        SourcePointer = CastI->getOperand(0);
        continue;
      }
      break;
    }

    // We can't scan through any more instructions; give up
    break;
  }

  //
  // If the pointer is a GEP, then as long as it has a DSNode, it has been
  // checked or proven safe.
  //
  Instruction * I;
  if ((I = dyn_cast<GetElementPtrInst>(SourcePointer)) &&
     (getDSNode (I, I->getParent()->getParent())) &&
     (getPoolHandle(I, I->getParent()->getParent()))) {
    return true;
  }
#if 0
  return (CheckedValues.find (SourcePointer) != CheckedValues.end());
#else
  // Return false; check must dominate load/store.
  return false;
#endif
}

//
// Function: findSourcePointer()
//
// Description:
//  Given a pointer value, attempt to find a source of the pointer that can
//  be used in an exactcheck().
//
// Outputs:
//  indexed - Flags whether the data flow went through a indexing operation
//            (i.e. a GEP).  This value is always written.
//
static Value *
findSourcePointer (Value * PointerOperand, bool & indexed) {
  //
  // Attempt to look for the originally allocated object by scanning the data
  // flow up.
  //
  indexed = false;
  Value * SourcePointer = PointerOperand;
  Value * OldSourcePointer = 0;
  while (!isEligableForExactCheck (SourcePointer)) {
    assert (OldSourcePointer != SourcePointer);
    OldSourcePointer = SourcePointer;
    // Check for GEP and cast constant expressions
    if (ConstantExpr * cExpr = dyn_cast<ConstantExpr>(SourcePointer)) {
      if ((cExpr->getOpcode() == Instruction::Cast) ||
          (cExpr->getOpcode() == Instruction::GetElementPtr)) {
        if (isa<PointerType>(cExpr->getOperand(0)->getType())) {
          SourcePointer = cExpr->getOperand(0);
          continue;
        }
      }
      // We cannot handle this expression; break out of the loop
      break;
    }

    // Check for GEP and cast instructions
    if (GetElementPtrInst * G = dyn_cast<GetElementPtrInst>(SourcePointer)) {
      SourcePointer = G->getPointerOperand();
      indexed = true;
      continue;
    }

    if (CastInst * CastI = dyn_cast<CastInst>(SourcePointer)) {
      if (isa<PointerType>(CastI->getOperand(0)->getType())) {
        SourcePointer = CastI->getOperand(0);
        continue;
      }
      break;
    }

    // Check for call instructions to exact checks.
    CallInst * CI1;
    if ((CI1 = dyn_cast<CallInst>(SourcePointer)) &&
        (CI1->getCalledFunction()) &&
        (CI1->getCalledFunction()->getName() == "exactcheck3")) {
      SourcePointer = CI1->getOperand (2);
      continue;
    }

    // We can't scan through any more instructions; give up
    break;
  }

  if (isEligableForExactCheck (SourcePointer))
    PointerOperand = SourcePointer;

  return PointerOperand;
}

//
// Function: insertExactCheck()
//
// Description:
//  Attepts to insert an efficient, accurate array bounds check for the given
//  GEP instruction; this check will not use Pools are MetaPools.
//
// Return value:
//  true  - An exactcheck() was successfully added.
//  false - An exactcheck() could not be added; a more extensive check will be
//          needed.
//
bool
InsertPoolChecks::insertExactCheck (GetElementPtrInst * GEP) {
  // The GEP instruction casted to the correct type
  Instruction *Casted = GEP;

  // The pointer operand of the GEP expression
  Value * PointerOperand = GEP->getPointerOperand();

  //
  // Get the DSNode for the instruction
  //
  Function *F   = GEP->getParent()->getParent();
  DSGraph & TDG = TDPass->getDSGraph(*F);
  DSNode * Node = TDG.getNodeForValue(GEP).getNode();
  assert (Node && "boundscheck: DSNode is NULL!");

  //
  // Determine whether an alignment check is needed.  This occurs when a DSNode
  // is type unknown (collapsed) but has pointers to type known (uncollapsed)
  // DSNodes.
  //
  if (preSCPass->nodeNeedsAlignment (Node)) {
    ++AlignChecks;
  }

#if 0
  // Debugging: See if we're missing exactcheck opportunities
  if (isa<SelectInst>(PointerOperand))
    std::cerr << "LLVA: EC: Select Inst\n";

  if (isa<GetElementPtrInst>(PointerOperand))
    std::cerr << "LLVA: EC: GEP: In " << F->getName() << "\n";

  CallInst * CI1;
  if ((CI1 = dyn_cast<CallInst>(PointerOperand)) &&
      (CI1->getCalledFunction()) &&
      (CI1->getCalledFunction()->getName() == "exactcheck3"))
    std::cerr << "LLVA: EC: GEP: Hidden by ec3: In " << F->getName() << "\n";

  PHINode * PN = 0;
  if (PN = dyn_cast<PHINode>(PointerOperand)) {
    std::cerr << "LLVA: EC: PHI\n";
    for (unsigned index = 0; index < PN->getNumIncomingValues(); ++index) {
      std::cerr << "LLVA: " << *(PN->getIncomingValue(index)) << std::endl;
    }
  }
#endif

  //
  // Attempt to find the object which we need to check.
  //
  bool WasIndexed = true;
  PointerOperand = findSourcePointer (PointerOperand, WasIndexed);

  //
  // Ensure the pointer operand really is a pointer.
  //
  if (!isa<PointerType>(PointerOperand->getType()))
    return false;

  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
    //
    // Attempt to remove checks on GEPs that only index into structures.
    // These criteria must be met:
    //  1) The pool must be Type-Homogoneous.
    //
#if 0
    if ((!(Node->isNodeCompletelyFolded())) &&
        (indexesStructsOnly (GEP))) {
      ++StructGEPsRemoved;
      return true;
    }
#endif

    //
    // Attempt to use a call to exactcheck() to check this value if it is a
    // global array with a non-zero size.  We do not check zero length arrays
    // because in C they are often used to declare an external array of unknown
    // size as follows:
    //        extern struct foo the_array[];
    //
    const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType());
    if ((!WasIndexed) && AT && (AT->getNumElements())) {
      // we need to insert an actual check
      // It could be a select instruction
      // First get the size
      // This only works for one or two dimensional arrays
      if (GEP->getNumOperands() == 2) {
        Value *secOp = GEP->getOperand(1);

        const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
        ConstantInt * Bounds = ConstantInt::get(csiType,AT->getNumElements());
        addExactCheck (GEP, secOp, Bounds);
        return true;
      } else if (GEP->getNumOperands() == 3) {
        if (ConstantInt *COP = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
          //FIXME assuming that the first array index is 0
          assert((COP->getZExtValue() == 0) && "non zero array index\n");

          Value * secOp = GEP->getOperand(2);
          const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
          ConstantInt * Bounds = ConstantInt::get(csiType,AT->getNumElements());
          addExactCheck (GEP, secOp, Bounds);
          return true;
        } else {
          // TODO:
          //  Handle non constant index two dimensional arrays later
          Value* Size=ConstantInt::get(Type::IntTy, TD->getTypeSize(GV->getType()));
          addExactCheck2 (PointerOperand, GEP, Size, GEP->getNext());
          return true;
        }
      } else {
        // Handle Multi dimensional cases later
        Value* AllocSize=ConstantInt::get(Type::IntTy, TD->getTypeSize(GV->getType()->getElementType()));
        addExactCheck2 (PointerOperand, GEP, AllocSize, GEP->getNext());
        return true;
        GEP->dump();
        ++MissedMultDimArrayChecks;
      }
      DEBUG(std::cerr << " Global variable ok \n");
    } else {
      Value* Size=ConstantInt::get(Type::IntTy, TD->getTypeSize(GV->getType()));
      addExactCheck2 (PointerOperand, GEP, Size, GEP->getNext());
      return true;
    }
  }

  //
  // If the pointer was generated by a dominating alloca instruction, we can
  // do an exactcheck on it, too.
  //
  if (AllocaInst *AI = dyn_cast<AllocaInst>(PointerOperand)) {
    //
    // Attempt to remove checks on GEPs that only index into structures.
    // These criteria must be met:
    //  1) The pool must be Type-Homogoneous.
    //
#if 0
    if ((!(Node->isNodeCompletelyFolded())) &&
        (indexesStructsOnly (GEP))) {
      ++StructGEPsRemoved;
      return true;
    }
#endif

    const Type * AllocaType = AI->getAllocatedType();
    Value *AllocSize=ConstantInt::get(Type::IntTy, TD->getTypeSize(AllocaType));

    if (AI->isArrayAllocation())
      AllocSize = BinaryOperator::create(Instruction::Mul,
                                         AllocSize,
                                         AI->getOperand(0), "sizetmp", GEP);

    addExactCheck2 (PointerOperand, GEP, AllocSize, GEP->getNext());
    return true;
  }

  //
  // If the pointer was an allocation, we should be able to do exact checks
  //
  if(CallInst* CI = dyn_cast<CallInst>(PointerOperand)) {
    if (CI->getCalledFunction() &&
        (CI->getCalledFunction()->getName() == "__vmalloc" || 
         CI->getCalledFunction()->getName() == "kmalloc")) {
      //
      // Attempt to remove checks on GEPs that only index into structures.
      // These criteria must be met:
      //  1) The pool must be Type-Homogoneous.
      //
#if 0
      if ((!(Node->isNodeCompletelyFolded())) &&
          (indexesStructsOnly (GEP))) {
        ++StructGEPsRemoved;
        return true;
      }
#endif

      Value* Cast = new CastInst(CI->getOperand(1), Type::IntTy, "", GEP);
      addExactCheck2(PointerOperand, GEP, Cast, GEP->getNext());
      return true;
    }
  }

  //
  // If the pointer is to a structure, we may be able to perform a simple
  // exactcheck on it, too, unless the array is at the end of the structure.
  // Then, we assume it's a variable length array and must be full checked.
  //
#if 0
  if (const PointerType * PT = dyn_cast<PointerType>(PointerOperand->getType()))
    if (const StructType *ST = dyn_cast<StructType>(PT->getElementType())) {
      const Type * CurrentType = ST;
      ConstantInt * C;
      for (unsigned index = 2; index < GEP->getNumOperands() - 1; ++index) {
        //
        // If this GEP operand is a constant, index down into the next type.
        //
        if (C = dyn_cast<ConstantInt>(GEP->getOperand(index))) {
          if (const StructType * ST2 = dyn_cast<StructType>(CurrentType)) {
            CurrentType = ST2->getElementType(C->getZExtValue());
            continue;
          }

          if (const ArrayType * AT = dyn_cast<ArrayType>(CurrentType)) {
            CurrentType = AT->getElementType();
            continue;
          }

          // We don't know how to handle this type of element
          break;
        }

        //
        // If the GEP operand is not constant and points to an array type,
        // then try to insert an exactcheck().
        //
        const ArrayType * AT;
        if ((AT = dyn_cast<ArrayType>(CurrentType)) && (AT->getNumElements())) {
          const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
          ConstantInt * Bounds = ConstantInt::get(csiType,AT->getNumElements());
          addExactCheck (GEP, GEP->getOperand (index), Bounds);
          return true;
        }
      }
    }
#endif

  /*
   * We were not able to insert a call to exactcheck().
   */
  return false;
}

//
// Function: insertExactCheck()
//
// Description:
//  Attepts to insert an efficient, accurate array bounds check for the given
//  GEP instruction; this check will not use Pools are MetaPools.
//
// Inputs:
//  I        - The instruction for which we are adding the check.
//  Src      - The pointer that needs to be checked.
//  Size     - The size, in bytes, that will be read/written by instruction I.
//  InsertPt - The instruction before which the check should be inserted.
//
// Return value:
//  true  - An exactcheck() was successfully added.
//  false - An exactcheck() could not be added; a more extensive check will be
//          needed.
//
bool
InsertPoolChecks::insertExactCheck (Instruction * I,
                                    Value * Src,
                                    Value * Size,
                                    Instruction * InsertPt) {
  // The pointer operand of the GEP expression
  Value * PointerOperand = Src;

  //
  // Get the DSNode for the instruction
  //
#if 1
  Function *F   = I->getParent()->getParent();
  DSGraph & TDG = TDPass->getDSGraph(*F);
  DSNode * Node = TDG.getNodeForValue(I).getNode();
  if (!Node)
    return false;
#endif

  //
  // Determine whether an alignment check is needed.  This occurs when a DSNode
  // is type unknown (collapsed) but has pointers to type known (uncollapsed)
  // DSNodes.
  //
  if (preSCPass->nodeNeedsAlignment (Node)) {
    ++AlignChecks;
  }

  //
  // Attempt to find the original object for which this check applies.
  // This involves unpeeling casts, GEPs, etc.
  //
  bool WasIndexed = true;
  PointerOperand = findSourcePointer (PointerOperand, WasIndexed);

  //
  // Ensure the pointer operand really is a pointer.
  //
  if (!isa<PointerType>(PointerOperand->getType()))
  {
    return false;
  }

  //
  // Attempt to use a call to exactcheck() to check this value if it is a
  // global array with a non-zero size.  We do not check zero length arrays
  // because in C they are often used to declare an external array of unknown
  // size as follows:
  //        extern struct foo the_array[];
  //
  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
    const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
    unsigned int arraysize = TD->getTypeSize(GV->getType()->getElementType());
    ConstantInt * Bounds = ConstantInt::get(csiType, arraysize);
    if (WasIndexed)
      addExactCheck2 (PointerOperand, Src, Bounds, InsertPt);
    else
      addExactCheck (Src, Size, Bounds, InsertPt);
    return true;
  }

  //
  // If the pointer was generated by a dominating alloca instruction, we can
  // do an exactcheck on it, too.
  //
  if (AllocaInst *AI = dyn_cast<AllocaInst>(PointerOperand)) {
    const Type * AllocaType = AI->getAllocatedType();
    Value *AllocSize=ConstantInt::get(Type::IntTy, TD->getTypeSize(AllocaType));

    if (AI->isArrayAllocation())
      AllocSize = BinaryOperator::create(Instruction::Mul,
                                         AllocSize,
                                         AI->getOperand(0), "allocsize", InsertPt);

    if (WasIndexed)
      addExactCheck2 (PointerOperand, Src, AllocSize, InsertPt);
    else
      addExactCheck (Src, Size, AllocSize, InsertPt);
    return true;
  }

  //
  // If the pointer was an allocation, we should be able to do exact checks
  //
  if(CallInst* CI = dyn_cast<CallInst>(PointerOperand)) {
    if (CI->getCalledFunction() && (
                              CI->getCalledFunction()->getName() == "__vmalloc" || 
                              CI->getCalledFunction()->getName() == "kmalloc")) {
      Value* Cast = new CastInst(CI->getOperand(1), Type::IntTy, "allocsize", InsertPt);
      if (WasIndexed)
        addExactCheck2 (PointerOperand, Src, Cast, InsertPt);
      else
        addExactCheck (Src, Size, Cast, InsertPt);
      return true;
    }
  }

  //
  // We were not able to insert a call to exactcheck().
  //
  return false;
}

bool
InsertPoolChecks::doInitialization (Module & M) {
  // Add the new poolcheck prototype 
  addPoolCheckProto (M);

  return true;
}

bool
InsertPoolChecks::doFinalization (Module & M) {
  // Insert code to register heap allocations with the correct MetaPool
  // and to register kernel pools with the correct MetaPool
  addHeapRegs (M);

  // Insert code to drop objects from MetaPools when they are freed by the
  // kernel allocators
  addObjFrees (M);

  return true;
}

bool
InsertPoolChecks::runOnFunction (Function & F) {
  //
  // Retrieve references to all of the passes from which we will gather
  // information.
  //
  preSCPass = &getAnalysis<PreInsertPoolChecks>();
  cuaPass   = &getAnalysis<ConvertUnsafeAllocas>();
  TD        = &getAnalysis<TargetData>();
  scevPass  = &getAnalysis<ScalarEvolution>();
  LI        = &getAnalysis<LoopInfo>();
#ifdef LLVA_KERNEL  
  TDPass  = &getAnalysis<TDDataStructures>();
#else
  paPass    = &getAnalysis<PoolAllocate>();
  equivPass = &(paPass->getECGraphs());
  efPass    = &getAnalysis<EmbeCFreeRemoval>();
  TD        = &getAnalysis<TargetData>();
#endif

#if 1
  // Transform the function
  if (!(F.isExternal())) TransformFunction (F);
  if (!DisableLSChecks)  addLoadStoreChecks(F);
#endif

  //
  // Update the statistics.
  //
  PoolChecks = NullChecks + FullChecks;
  
  return true;
}

void InsertPoolChecks::handleCallInst(CallInst *CI) {
  //
  // Determine if this is an indirect call.  If so, insert a run-time check for
  // it.
  //
  if (!(CI->getCalledFunction()))
    insertFunctionCheck (CI);

  //
  // Check for intrinsic functions and add checks as necessary.
  //
  if (CI && (!DisableIntrinsicChecks)) {
    Value *Fop = CI->getOperand(0);
    Function *F = CI->getParent()->getParent();
#ifdef LLVA_KERNEL    
    std::string FuncName = Fop->getName();
    if ((FuncName == "llvm.memcpy.i32")    || 
        (FuncName == "llvm.memcpy.i64")    ||
        (FuncName == "llvm.memset.i32")    ||
        (FuncName == "llvm.memset.i64")    ||
        (FuncName == "llvm.memmove.i32")   ||
        (FuncName == "llvm.memmove.i64")   ||
        (FuncName == "llva_memcpy")        ||
        (FuncName == "llva_memset")        ||
        (FuncName == "llva_strncpy")       ||
        (FuncName == "llva_invokememcpy")  ||
        (FuncName == "llva_invokestrncpy") ||
        (FuncName == "llva_invokememset")  ||
        (FuncName == "memcmp")) {
      //
      // Create a call to an accurate bounds check for each string parameter.
      //
      Instruction *InsertPt = CI;
      Value * CastPointer1 = castTo (CI->getOperand(1), Type::UIntTy, InsertPt);
      Value * CastPointer2 = castTo (CI->getOperand(2), Type::UIntTy, InsertPt);
      Value * CastCIOp3    = castTo (CI->getOperand(3), Type::UIntTy, InsertPt);

      Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
                                                 CastCIOp3, "mcadd",InsertPt);
      Instruction *Bop2 = BinaryOperator::create(Instruction::Add, CastPointer2,
                                                 CastCIOp3, "mcadd",InsertPt);
      Instruction *Finalp1 = BinaryOperator::create(Instruction::Sub, Bop1,
                                                 ConstantInt::get (Type::UIntTy, 1), "mcsub",InsertPt);
      Instruction *Finalp2 = BinaryOperator::create(Instruction::Sub, Bop2,
                                                 ConstantInt::get (Type::UIntTy, 1), "mcsub",InsertPt);

      Instruction *Length = BinaryOperator::create(Instruction::Sub, CastCIOp3,
                                                ConstantInt::get (Type::UIntTy, 1), "mclen",InsertPt);
      AddedValues.insert(CastPointer1);
      AddedValues.insert(CastPointer2);
      AddedValues.insert(CastCIOp3);
      AddedValues.insert(Bop1);
      AddedValues.insert(Bop2);
      AddedValues.insert(Finalp1);
      AddedValues.insert(Finalp2);
      AddedValues.insert(Length);

      // Create the call to do an accurate bounds check
      if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
        insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
      if (!insertExactCheck(CI, CI->getOperand(2), Length, InsertPt))
        insertBoundsCheck (CI, CI->getOperand(2), Bop2, InsertPt);
#if 0
    } else if ((FuncName == "llva_load_integer") ||
               (FuncName == "llva_save_integer") ||
               (FuncName == "llva_load_integer_stackp") ||
               (FuncName == "llva_save_integer_stackp") ||
               (FuncName == "llva_push_function1")) {
      //
      // Create a call to an accurate bounds check for the integer state
      // pointer.
      //
      Instruction *InsertPt = CI;
      Value * CastPointer1 = castTo (CI->getOperand(1), Type::UIntTy, InsertPt);
      Value * CastLength   = ConstantInt::get (Type::UIntTy, LLVA_INTEGERSTATE_SIZE);

      Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
                                                 CastLength, "mcadd",InsertPt);
      Value *Length = ConstantInt::get (Type::UIntTy, LLVA_INTEGERSTATE_SIZE - 1);

      // Create the call to do an accurate bounds check
      if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
        insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
    } else if ((FuncName == "llva_load_icontext") ||
               (FuncName == "llva_save_icontext")) {
      //
      // Perform a check on the interrupt context.
      //
      Instruction *InsertPt = CI;
      insertICCheck (CI->getOperand(1), InsertPt);

      //
      // Create a call to an accurate bounds check for the integer state.
      //
      Value * CastPointer1 = castTo (CI->getOperand(2), Type::UIntTy, InsertPt);
      Value * CastLength   = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE);

      Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
                                                 CastLength, "mcadd",InsertPt);
      Value *Length = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE - 1);

      // Create the call to do an accurate bounds check
      if (!insertExactCheck(CI, CI->getOperand(2), Length, InsertPt))
        insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
    } else if ((FuncName == "llva_load_fp") || (FuncName == "llva_save_fp")) {
      //
      // Create a call to an accurate bounds check for the FP state
      // pointer.
      //
      Instruction *InsertPt = CI;
      Value * CastPointer1 = castTo (CI->getOperand(1), Type::UIntTy, InsertPt);
      Value * CastLength   = ConstantInt::get (Type::UIntTy, LLVA_FPSTATE_SIZE);

      Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
                                                 CastLength, "mcadd",InsertPt);
      Value *Length = ConstantInt::get (Type::UIntTy, LLVA_FPSTATE_SIZE - 1);

      // Create the call to do an accurate bounds check
      if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
        insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
    } else if (FuncName == "llva_push_syscall") {
      //
      // Create a call to an accurate bounds check for the interrupt context
      // pointer.
      //
      Instruction *InsertPt = CI;
      Value * CastPointer1 = castTo (CI->getOperand(2), Type::UIntTy, InsertPt);
      Value * CastLength   = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE);

      Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
                                                 CastLength, "mcadd",InsertPt);
      Value *Length = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE - 1);

      // Create the call to do an accurate bounds check
      if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
        insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
    } else if ((FuncName == "llva_init_icontext") ||
               (FuncName == "llva_clear_icontext") ||
               (FuncName == "llva_was_privileged") ||
               (FuncName == "llva_icontext_lif") ||
               (FuncName == "llva_ipop_function0") ||
               (FuncName == "llva_ipush_function0") ||
               (FuncName == "llva_ipush_function1") ||
               (FuncName == "llva_ipush_function3") ||
               (FuncName == "llva_ialloca") ||
               (FuncName == "llva_unwind") ||
               (FuncName == "llva_icontext_load_retvalue") ||
               (FuncName == "llva_icontext_save_retvalue") ||
               (FuncName == "llva_get_icontext_stackp") ||
               (FuncName == "llva_set_icontext_stackp") ||
               (FuncName == "llva_iset_privileged")) {
      //
      // Create a call to an accurate bounds check for the interrupt context
      // pointer.
      //
      Instruction *InsertPt = CI;
      insertICCheck (CI->getOperand(1), InsertPt);
#endif
    }
#endif    
  }
}

void InsertPoolChecks::simplifyGEPList() {
#if 0
  std::set<Instruction *> & UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC();
  std::map< std::pair<Value*, BasicBlock*>, std::set<Instruction*> > m;
  for (std::set<Instruction *>::iterator ii = UnsafeGetElemPtrs.begin(), ee = UnsafeGetElemPtrs.end();
       ii != ee; ++ii) {
    GetElementPtrInst* GEP = cast<GetElementPtrInst>(*ii);
    m[std::make_pair(GEP->getOperand(0), GEP->getParent())].insert(GEP);
  }

  unsigned singletons;
  unsigned multi;
  for (std::map< std::pair<Value*,BasicBlock*>, std::set<Instruction*> >::iterator ii = m.begin(), ee = m.end();
       ii != ee; ++ii) {
    if (ii->second.size() > 1) {
      std::cerr << "##############\n";
      for (std::set<Instruction *>::iterator i = ii->second.begin(), e = ii->second.end();
       i != e; ++i) {
        (*i)->dump();
      }
      std::cerr << "##############\n";
      ++multi;
    } else
      ++singletons;
  }

  std::cerr << "Singletons: " << singletons << " Multitons: " << multi << "\n";

#endif
}

//
// Function: compatibleGEPs()
//
// Description:
//  Determine whether two GEPs address the same memory and have the (save the
//  for last) same arguments.
//
// Return value:
//  true  - All arguments (except possibly the last) are identical.
//  false - One or more arguments besides the last argument are different.
//
static inline bool
identicalGEPs (GetElementPtrInst * GEP1, GetElementPtrInst * GEP2) {
  if (GEP1->getPointerOperand() != GEP2->getPointerOperand()) return false;
  if (GEP1->getNumOperands()    != GEP2->getNumOperands())    return false;
  for (unsigned index = 0; index < GEP1->getNumOperands() - 1; ++index) {
    if (GEP1->getOperand(index) != GEP2->getOperand(index)) {
      return false;
      break;
    }
  }

  return true;
}

bool
InsertPoolChecks::AggregateGEPs (GetElementPtrInst * MAI,
                                 std::set<Instruction *> & RelatedGEPs) {
  // Get the set of unsafe GEPs for this instruction's basic block
  std::set<Instruction *> * UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC(MAI->getParent());
  if (!UnsafeGetElemPtrs) {
    RelatedGEPs.insert (MAI);
    return true;
  }

  // If this GEP has already been deemed safe, then return;
  std::set<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs->find(MAI);
  if (iCurrent == UnsafeGetElemPtrs->end()) {
    return true;
  }

  // Determine whether the GEP has a constant as its last index.
  // If so, search for all other GEPs that have, save for the last index,
  // identical operands.  Then select the two with the higest and lowest
  // indices; we will perform our run-time checks on these.
  std::set<Instruction *>::iterator UGI = UnsafeGetElemPtrs->begin(),
                                    UGE = UnsafeGetElemPtrs->end();
  Instruction * MinGEP = MAI;
  Instruction * MaxGEP = MAI;
  if (isa<ConstantInt>(MAI->getOperand((MAI->getNumOperands() - 1)))) {

    for (;UGI != UGE; ++UGI) {
      Instruction * I = *UGI;
      GetElementPtrInst * GEP = dyn_cast<GetElementPtrInst>(I);
      if (!GEP) continue;
      if (!(isa<ConstantInt>(GEP->getOperand((GEP->getNumOperands() - 1))))) continue;
      if (identicalGEPs (GEP, MAI)) {
        ConstantInt * GEPLastIndex;
        ConstantInt * MinLastIndex;
        ConstantInt * MaxLastIndex;
        GEPLastIndex = dyn_cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1));
        MinLastIndex = dyn_cast<ConstantInt>(MinGEP->getOperand(MinGEP->getNumOperands() - 1));
        MaxLastIndex = dyn_cast<ConstantInt>(MaxGEP->getOperand(MaxGEP->getNumOperands() - 1));
        if (GEPLastIndex->getSExtValue() < MinLastIndex->getSExtValue()) {
          UnsafeGetElemPtrs->erase (MinGEP);
          MinGEP = GEP;
        }
        if (GEPLastIndex->getSExtValue() > MaxLastIndex->getSExtValue()) {
          UnsafeGetElemPtrs->erase (MaxGEP);
          MaxGEP = GEP;
        }
      }
    }

    //
    // Find the first compatible GEP in the basic block.
    //
    Instruction * Ins = MAI->getParent()->getFirstNonPHI();
    GetElementPtrInst * FirstGEP = 0;
    while (!(Ins->isTerminator())) {
      if (FirstGEP = dyn_cast<GetElementPtrInst>(Ins)) {
        if (identicalGEPs (MAI, FirstGEP))
          break;
      }
      Ins = Ins->getNext();
    }

    //
    // Move the minimum and maximum GEPs to before the first identical GEP.
    //
    if (FirstGEP != MinGEP) {
      MinGEP->moveBefore (FirstGEP);
    }
    if (FirstGEP != MaxGEP) {
      MaxGEP->moveBefore (FirstGEP);
    }
  }

  RelatedGEPs.insert (MinGEP);
  if (MinGEP != MaxGEP) RelatedGEPs.insert (MaxGEP);

  return true;
}

void InsertPoolChecks::handleGetElementPtr(GetElementPtrInst *MAI) {
  // Get the set of unsafe GEP instructions from the array bounds check pass
  // If this instruction is not within that set, then the result of the GEP
  // instruction has been proven safe, and there is no need to insert a check.
  std::set<Instruction *> * UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC(MAI->getParent());
  if (!UnsafeGetElemPtrs) return;
  std::set<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs->find(MAI);
  if (iCurrent == UnsafeGetElemPtrs->end()) {
#if 0
    std::cerr << "statically proved safe : Not inserting checks " << *MAI << "\n";
#endif
    return;
  }

#if 0
  // Find all unsafe GEPs within the basic block that are identical save for
  // their last index
  std::set<Instruction *> RelatedGEPs;
  std::set<Instruction *>::iterator UGI = UnsafeGetElemPtrs->begin(),
                                    UGE = UnsafeGetElemPtrs->end();
  if (isa<ConstantInt>(MAI->getOperand((MAI->getNumOperands() - 1))))
    for (;UGI != UGE; ++UGI) {
      Instruction * I = *UGI;
      GetElementPtrInst * GEP = dyn_cast<GetElementPtrInst>(I);
      if (!GEP) continue;
      if (GEP->getPointerOperand() != MAI->getPointerOperand()) continue;
      if (GEP->getNumOperands() != MAI->getNumOperands()) continue;
      if (!(isa<ConstantInt>(GEP->getOperand((GEP->getNumOperands() - 1))))) continue;
      bool identical = true;
      for (unsigned index = 0; index < GEP->getNumOperands() - 1; ++index) {
        if (GEP->getOperand(index) != MAI->getOperand(index)) {
          identical = false;
          break;
        }
      }
      if (identical)
        RelatedGEPs.insert (GEP);
    }

  std::cerr << "LLVA: RelatedGEP: " << RelatedGEPs.size() << std::endl;
#endif

  if (InsertPoolChecksForArrays) {
    Function *F = MAI->getParent()->getParent();
    GetElementPtrInst *GEP = MAI;
    // Now we need to decide if we need to pass in the alignmnet
    //for the poolcheck
    //    if (getDSNodeOffset(GEP->getPointerOperand(), F)) {
    //          std::cerr << " we don't handle middle of structs yet\n";
    //assert(!getDSNodeOffset(GEP->getPointerOperand(), F) && " we don't handle middle of structs yet\n");
    //       ++MissChecks;
    //       continue;
    //     }

#ifndef LLVA_KERNEL
    PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
    Instruction *Casted = GEP;
    if (!FI->ValueMap.empty()) {
      assert(FI->ValueMap.count(GEP) && "Instruction not in the value map \n");
      Instruction *temp = dyn_cast<Instruction>(FI->ValueMap[GEP]);
      assert(temp && " Instruction  not there in the Value map");
      Casted  = temp;
    }
    if (GetElementPtrInst *GEPNew = dyn_cast<GetElementPtrInst>(Casted)) {
      Value *PH = getPoolHandle(GEP, F, *FI);
      if (PH && isa<ConstantPointerNull>(PH)) return;
      if (!PH) {
        Value *PointerOperand = GEPNew->getPointerOperand();
        if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(PointerOperand)) {
          if (cExpr->getOpcode() == Instruction::Cast)
            PointerOperand = cExpr->getOperand(0);
        }
        if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
          if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
            // We need to insert an actual check.  It could be a select
            // instruction.
            // First get the size.
            // This only works for one or two dimensional arrays.
            if (GEPNew->getNumOperands() == 2) {
              Value *secOp = GEPNew->getOperand(1);
              if (secOp->getType() != Type::IntTy) {
                secOp = new CastInst(secOp, Type::IntTy,
                                     secOp->getName()+".ec.casted", Casted);
              }

              const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
              std::vector<Value *> args(1,secOp);
              args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
              new CallInst(ExactCheck,args,"", Casted);
              DEBUG(std::cerr << "Inserted exact check call Instruction \n");
              return;
            } else if (GEPNew->getNumOperands() == 3) {
              if (ConstantInt *COP = dyn_cast<ConstantInt>(GEPNew->getOperand(1))) {
                // FIXME: assuming that the first array index is 0
                assert((COP->getZExtValue() == 0) && "non zero array index\n");
                Value * secOp = GEPNew->getOperand(2);
                if (secOp->getType() != Type::IntTy) {
                  secOp = new CastInst(secOp, Type::IntTy,
                                       secOp->getName()+".ec2.casted", Casted);
                }
                std::vector<Value *> args(1,secOp);
                const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
                args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
                new CallInst(ExactCheck, args, "", Casted->getNext());
                return;
              } else {
                // Handle non constant index two dimensional arrays later
                abort();
              }
            } else {
              // Handle Multi dimensional cases later
              DEBUG(std::cerr << "WARNING: Handle multi dimensional globals later\n");
              (*iCurrent)->dump();
            }
          }
          DEBUG(std::cerr << " Global variable ok \n");
        }

        //      These must be real unknowns and they will be handled anyway
        //      std::cerr << " WARNING, DID NOT HANDLE   \n";
        //      (*iCurrent)->dump();
        return;
      } else {
        if (Casted->getType() != PointerType::get(Type::SByteTy)) {
          Casted = new CastInst(Casted,PointerType::get(Type::SByteTy),
                                (Casted)->getName()+".pc.casted",
                                (Casted)->getNext());
        }
        std::vector<Value *> args(1, PH);
        args.push_back(Casted);
        // Insert it
        new CallInst(PoolCheck,args, "",Casted->getNext());
        DEBUG(std::cerr << "inserted instrcution \n");
      }
    }
#else
    //
    // Get the pool handle associated with the pointer operand.
    //
    Value *PH = getPoolHandle(GEP->getPointerOperand(), F);
    GetElementPtrInst *GEPNew = GEP;
    Instruction *Casted = GEP;

    DSGraph & TDG = TDPass->getDSGraph(*F);
    DSNode * Node = TDG.getNodeForValue(GEP).getNode();

    DEBUG(std::cerr << "LLVA: addGEPChecks: Pool " << PH << " Node ");
    DEBUG(std::cerr << Node << std::endl);

    Value *PointerOperand = GEPNew->getPointerOperand();
    if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(PointerOperand)) {
      if (cExpr->getOpcode() == Instruction::Cast)
        PointerOperand = cExpr->getOperand(0);
    }
    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
      if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
        // we need to insert an actual check
        // It could be a select instruction
        // First get the size
        // This only works for one or two dimensional arrays
        if (GEPNew->getNumOperands() == 2) {
          Value *secOp = GEPNew->getOperand(1);
#ifdef LLVA_KERNEL
          //
          // Determine whether the exactcheck() will have constant integer
          // arguments.  If so, then we can evaluate them statically and avoid
          // inserting the run-time check.
          //
          if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
            int index = Index->getSExtValue();
            assert ((index < 0) && "exactcheck will fail at runtime");
            if (index < AT->getNumElements())
              return;
            assert (0 && "exactcheck out of range");
          }
#endif
          if (secOp->getType() != Type::IntTy) {
            secOp = new CastInst(secOp, Type::IntTy,
                                 secOp->getName()+".ec3.casted", Casted);
          }
          
          std::vector<Value *> args(1,secOp);
          const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
          args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
          new CallInst(ExactCheck,args,"", Casted);
          //	    DEBUG(std::cerr << "Inserted exact check call Instruction \n");
          return;
        } else if (GEPNew->getNumOperands() == 3) {
          if (ConstantInt *COP = dyn_cast<ConstantInt>(GEPNew->getOperand(1))) {
            //FIXME assuming that the first array index is 0
            assert((COP->getZExtValue() == 0) && "non zero array index\n");
            Value * secOp = GEPNew->getOperand(2);
#ifdef LLVA_KERNEL
            //
            // Determine whether the exactcheck() will have constant integer
            // arguments.  If so, then we can evaluate them statically and avoid
            // inserting the run-time check.
            //
            if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
              int index = Index->getSExtValue();
              assert ((index < 0) && "exactcheck will fail at runtime");
              if (index < AT->getNumElements())
                return;
              assert (0 && "exactcheck out of range");
            }
#endif
            if (secOp->getType() != Type::IntTy) {
              secOp = new CastInst(secOp, Type::IntTy,
                                   secOp->getName()+".ec4.casted", Casted);
            }
            std::vector<Value *> args(1,secOp);
            const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
            args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
            new CallInst(ExactCheck,args,"", Casted->getNext());
            return;
          } else {
            //Handle non constant index two dimensional arrays later
            abort();
          }
        } else {
          //Handle Multi dimensional cases later
          std::cerr << "WARNING: Handle multi dimensional globals later\n";
          (*iCurrent)->dump();
          ++MissedMultDimArrayChecks;
        }
        DEBUG(std::cerr << " Global variable ok \n");
      }
    }

    //
    // We cannot insert an exactcheck().  Insert a pool check.
    //
    // 
    if (!PH) {
#if 0
      std::cerr << "missing a GEP check for" << *MAI << "alloca case?\n";
#endif
      ++NullChecks;
      if (!PH) ++MissedNullChecks;
      // Don't bother to insert the NULL check unless the user asked
      if (!EnableNullChecks)
        return;
      PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
    } else {
      assert ((isa<GlobalValue>(PH)) && "MetaPool Handle is not a global!");
    }

    //
    // If this is a complete node, insert a poolcheck.
    // If this is an icomplete node, insert a poolcheckarray.
    //
    Instruction *InsertPt = Casted->getNext();
    if (Casted->getType() != PointerType::get(Type::SByteTy)) {
      Casted = new CastInst(Casted,PointerType::get(Type::SByteTy),
                            (Casted)->getName()+".pc2.casted",InsertPt);
    }
    Instruction *CastedPointerOperand = new CastInst(PointerOperand,
                                                     PointerType::get(Type::SByteTy),
                                                     PointerOperand->getName()+".casted",InsertPt);
    Instruction *CastedPH = new CastInst(PH,
                                         PointerType::get(Type::SByteTy),
                                         "ph",InsertPt);
    if (Node->isIncomplete()) {
      std::vector<Value *> args(1, CastedPH);
      args.push_back(CastedPointerOperand);
      args.push_back(Casted);
      CallInst(PoolCheckArray,args, "",InsertPt);
    } else {
      std::vector<Value *> args(1, CastedPH);
      args.push_back(Casted);
      new CallInst(PoolCheck,args, "",InsertPt);
    }
#endif
  } else {
    // Insert accurate bounds checks for arrays (as opposed to poolchecks)

    //
    // Attempt to insert a standard exactcheck() call for the GEP.
    //
    if (insertExactCheck (MAI))
      return;

    //Exact poolchecks
    if (const PointerType *PT = dyn_cast<PointerType>(MAI->getPointerOperand()->getType())) {
#if 0
      if (const StructType *ST = dyn_cast<StructType>(PT->getElementType())) {
#else
      const StructType *ST = dyn_cast<StructType>(PT->getElementType());
      if (0) {
#endif
        //It is a struct type with pointers
        //for each pointer with struct typ
        //we need to watchg out for arrays inside structs 
        if (ConstantInt *COP = dyn_cast<ConstantInt>(MAI->getOperand(1))) {
          //FIXME assuming that the first index is safe
          //assert((COP->getRawValue() == 0) && "non zero array index\n");
          bool allconstant = true;
          for (unsigned i = 2; i < MAI->getNumOperands(); ++i) {
            if (!isa<Constant>(MAI->getOperand(i))) {
              allconstant = false;
              break;
            }
          }
          if (!allconstant) {
            if (MAI->getNumOperands() == 4) {
              if (ConstantInt *COPi = dyn_cast<ConstantInt>(MAI->getOperand(2))) {
                const Type *stel = ST->getElementType(COPi->getZExtValue());
                if (const ArrayType *elAT = dyn_cast<ArrayType>(stel)) {
                  //Need to factor this in to separate method!!!
                  Value * secOp = MAI->getOperand(3);
                  Value *indexTypeSize = ConstantInt::get(Type::UIntTy, TD->getTypeSize(secOp->getType())); 
#ifdef LLVA_KERNEL
                  //
                  // Determine whether the exactcheck() will have constant integer
                  // arguments.  If so, then we can evaluate them statically and avoid
                  // inserting the run-time check.
                  //
                  if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
                    int index = Index->getSExtValue();
                    assert ((index < 0) && "exactcheck will fail at runtime");
                    if (index < TD->getTypeSize(elAT))
                      return;
                    assert (0 && "exactcheck out of range");
                  }
#endif
                  if (secOp->getType() != Type::IntTy) {
                    secOp = new CastInst(secOp, Type::IntTy,
                                         secOp->getName()+".casted",  MAI);
                  }
                  //                      secOp = BinaryOperator::create(Instruction::Mul, indexTypeSize, secOp,"indextmp", MAI);
                  std::vector<Value *> args(1,secOp);
                  Value *AllocSize =
                    ConstantInt::get(Type::IntTy, TD->getTypeSize(elAT));
                  /*
                    if (AI->isArrayAllocation())
                    AllocSize = BinaryOperator::create(Instruction::Mul,
                    AllocSize,
                    AI->getOperand(0), "sizetmp", MAI);
                  */
                  //		      args.push_back(ConstantInt::get(csiType,elAT->getNumElements()));
                  args.push_back(AllocSize);
                  new CallInst(ExactCheck,args,"",MAI);
			
                } else {
                  //non array, non constant value
                  abort();
                }
              } else {
                // non-constant value, not possible
                abort();
              }
            } else {
#if 0
              //FIXME this is a less precise check than possible
              //		  std::cerr << "WARNING : did not handle array within a struct precisely, num operands != 4\n";
              Instruction *InsertPt = MAI->getNext();
              Type *VoidPtrType = PointerType::get(Type::SByteTy); 
              Value *MAIPSbyte =  new CastInst(MAI->getPointerOperand(),
                                               VoidPtrType, 
                                               MAI->getPointerOperand()->getName()+".casted",InsertPt);
                  
              Value *MAISbyte =  new CastInst(MAI,
                                              VoidPtrType, 
                                              MAI->getName()+".casted",InsertPt);
                  
              std::vector<Value *> args(1,MAIPSbyte);
              args.push_back(MAISbyte);
              Value *AllocSize =
                ConstantInt::get(Type::UIntTy, TD->getTypeSize(ST));
              args.push_back(AllocSize);
              new CallInst(ExactCheck2,args,"",InsertPt);
#endif
            }
          } else {
            std::cerr << "Not all args constant: " << *MAI << std::endl;
          }
        } else {
          std::cerr << "HandleLikeArray: " << *MAI << std::endl;
          goto HandleThisLikeArray;
        }
      } else {
      HandleThisLikeArray:	      
        if (AllocaInst *AI = dyn_cast<AllocaInst>(MAI->getPointerOperand())) {
          //we can put an exact check here
          if (1 || (MAI->getNumOperands() == 3)) {
            if (ConstantInt *COP = dyn_cast<ConstantInt>(MAI->getOperand(1))) {
              //FIXME assuming that the first array index is 0
#if 0
              assert((COP->getZExtValue() == 0) && "non zero array index\n");
#else
              if (COP->getZExtValue() == 0) {
#endif
              Value * secOp = MAI->getOperand(2);
              Value *indexTypeSize = ConstantInt::get(Type::UIntTy, TD->getTypeSize(secOp->getType())); 
#ifdef LLVA_KERNEL
              //
              // Determine whether the exactcheck() will have constant integer
              // arguments.  If so, then we can evaluate them statically and avoid
              // inserting the run-time check.
              //
              if (!(AI->isArrayAllocation()))
                if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
                  int index = Index->getSExtValue();
                  if ((index > 0) && (index < TD->getTypeSize(AI->getAllocatedType())))
                    return;
                }
#endif
              //Convert everything to bytes
              if (secOp->getType() != Type::IntTy) {
                secOp = new CastInst(secOp, Type::IntTy, secOp->getName()+".casted",
                                     MAI);
              }
              //		  secOp = BinaryOperator::create(Instruction::Mul, indexTypeSize, secOp,"indextmp",MAI);
              std::vector<Value *> args(1,secOp);
              Value *AllocSize =
                ConstantInt::get(Type::IntTy, TD->getTypeSize(AI->getAllocatedType()));
		  
              if (AI->isArrayAllocation())
                AllocSize = BinaryOperator::create(Instruction::Mul,
                                                   AllocSize,
                                                   AI->getOperand(0), "sizetmp", MAI);
		  
              args.push_back(AllocSize);
              CallInst *newCI = new CallInst(ExactCheck,args,"", MAI);
              } else {
                std::cerr << "COP not zero: " << *MAI << std::endl;
              }
            } else {
              std::cerr << "Bad COP: " << *MAI << std::endl;
            }
          } else {
            std::cerr << " num operands != 3: " << *MAI << std::endl;
            abort();
          }
        } else {
          // Now check if the GEP is inside a loop with monotonically increasing
          //loop bounds
          //We use the LoopInfo Pass this
          Loop *L = LI->getLoopFor(MAI->getParent());
          bool monotonicOpt = false;
          if (L && (MAI->getNumOperands() == 2)) {
            bool HasConstantItCount = isa<SCEVConstant>(scevPass->getIterationCount(L));
            Value *vIndex = MAI->getOperand(1);
            if (Instruction *Index = dyn_cast<Instruction>(vIndex)) {
              //If it is not an instruction then it must already be loop invariant
              if (L->isLoopInvariant(MAI->getPointerOperand())) { 
                SCEVHandle SH = scevPass->getSCEV(Index);
                if (SH->hasComputableLoopEvolution(L) ||    // Varies predictably
                    HasConstantItCount) {
                  if (SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SH))
                    if (AR->isAffine()) {
                      SCEVHandle EntryValue = AR->getStart();
                      //                      EntryValue->getValueRange().dump();
                      //                      Index->dump();
                      SCEVHandle ExitValue = scevPass->getSCEVAtScope(Index, L->getParentLoop());
                      BasicBlock *Preheader = L->getLoopPreheader();
                      if (!isa<SCEVCouldNotCompute>(ExitValue)) {
                        SCEVExpander Rewriter(*scevPass, *LI);
                        Instruction *ptIns = Preheader->getTerminator();
                        Value *NewVal = Rewriter.expandCodeFor(ExitValue, ptIns,
                                                               Index->getType());
                        //                        NewVal->dump();
                        if (!isa<SCEVCouldNotCompute>(EntryValue)) {
                          Value *NewVal2 = Rewriter.expandCodeFor(EntryValue, ptIns,
                                                                  Index->getType());
                          //                          NewVal2->dump();
                          //Inserted the values now insert GEPs and add checks
                          std::vector<Value *> gepargs1(1,NewVal);
                          GetElementPtrInst *GEPUpper =
                            new GetElementPtrInst(MAI->getPointerOperand(), gepargs1, MAI->getName()+"upbc", ptIns);
                          insertBoundsCheck (MAI, GEPUpper->getPointerOperand(), GEPUpper, ptIns);
                          std::vector<Value *> gepargs2(1,NewVal2);
                          GetElementPtrInst *GEPLower =
                            new GetElementPtrInst(MAI->getPointerOperand(), gepargs2, MAI->getName()+"lobc", ptIns);
                          insertBoundsCheck (MAI, GEPLower->getPointerOperand(), GEPLower, ptIns);
                          monotonicOpt = true;
                          ++MonotonicOpts;
                        }
                      }
                    }
                }
              }
            }
          }
          if (!monotonicOpt) {
            //
            // Insert a bounds check and use its return value in all subsequent
            // uses.
            //
            Instruction *nextIns = MAI->getNext();
            insertBoundsCheck (MAI, MAI->getPointerOperand(), MAI, nextIns);
          }
        }
      }
    } else {
      std::cerr << "GEP does not have pointer type arg" << *MAI << std::endl;
      abort();
    }
  }
}

  void InsertPoolChecks::addGetActualValue(SetCondInst *SCI, unsigned operand) {
    //we know that the operand is a pointer type 
    Value *op = SCI->getOperand(operand);
    Function *F = SCI->getParent()->getParent();
#ifndef LLVA_KERNEL    
    if (!equivPass->ContainsDSGraphFor(*F)) {
      //some times the ECGraphs doesnt contain F
      //for newly created cloned functions
      PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
      op = FI->MapValueToOriginal(op);
      if (!op) return; //abort();
    }
#endif    
    Function *Fnew = F;
    Value *PH = 0;
    if (Argument *arg = dyn_cast<Argument>(op)) {
      Fnew = arg->getParent();
      PH = getPoolHandle(op, Fnew);
    } else if (Instruction *Inst = dyn_cast<Instruction>(op)) {
      Fnew = Inst->getParent()->getParent();
      PH = getPoolHandle(op, Fnew);
    } else if (isa<Constant>(op)) {
      return;
      //      abort();
    } else if (!isa<ConstantPointerNull>(op)) {
      //has to be a global
      abort();
    }
    op = SCI->getOperand(operand);
    if (!isa<ConstantPointerNull>(op)) {
      if (PH) {
	if (1) { //HACK fixed
	  Type *VoidPtrType = PointerType::get(Type::SByteTy); 
	  Value *PHVptr =  new CastInst(PH, VoidPtrType,
					PH->getName()+".casted",  SCI);
	  Value *OpVptr = op;
	  if (op->getType() != VoidPtrType)
	    OpVptr = new CastInst(op, VoidPtrType,
				  op->getName()+".casted",  SCI);
	  
	  std::vector<Value *> args = make_vector(PHVptr, OpVptr,0);
	  CallInst *CI = new CallInst(GetActualValue, args,"getval", SCI);
	  CastInst *CastBack = new CastInst(CI, op->getType(), op->getName()+".castback",SCI);
	  SCI->setOperand(operand, CastBack);
	}
      } else {
	//It shouldn't work if PH is not null
      }
    }
  }

void InsertPoolChecks::TransformFunction (Function & F) {
#ifndef LLVA_KERNEL  
  PA::FuncInfo * PAFI = paPass->getFuncInfoOrClone(F);
  if (PAFI->Clone && PAFI->Clone != &F) {
    //no need to transform
    return;
  }
#endif  
  inst_iterator I = inst_begin(F);
  while (I != inst_end(F)) {
    Instruction *iLocal = &*I;
    if (SetCondInst *SCI = dyn_cast<SetCondInst>(iLocal)) {
      //If it is neq, eq,
      if ((SCI->getOpcode() == BinaryOperator::SetEQ) || (SCI->getOpcode() == BinaryOperator::SetNE)) {
        //for all the pointer operands replace them by the getactualvalue
        assert((SCI->getNumOperands() == 2) && "nmber of operands for SCI different from 2 ");
        if (isa<PointerType>(SCI->getOperand(0)->getType())) {
          //we need to insert a call to getactualvalue
          //First get the poolhandle for the pointer
          // TODO: We don't have a working getactualvalue(), so don't waste
          // time calling it.
#if 0
          if ((!isa<ConstantPointerNull>(SCI->getOperand(0))) && (!isa<ConstantPointerNull>(SCI->getOperand(1)))) {
            addGetActualValue(SCI, 0);
            addGetActualValue(SCI, 1);
          }
#endif
        }
      }
    } else if (isa<CastInst>(iLocal)) {
      //Some times the getelementptr is an argument of cast instruction
      // and we don't want to miss a run-time check there
      if (isa<GetElementPtrInst>(iLocal->getOperand(0))) {
        iLocal = cast<Instruction>(iLocal->getOperand(0));
      }
    } //

    // we need to handle
    // alloca instructions
    // getelement ptrs
    // load store checks 
    if (isa<GetElementPtrInst>(iLocal)) {
      GetElementPtrInst *MAI = cast<GetElementPtrInst>(iLocal);
      ++I;
      std::set<Instruction *> CheckSet;
      AggregateGEPs (MAI, CheckSet);
      for (std::set<Instruction *>::iterator GEP = CheckSet.begin();
           GEP != CheckSet.end(); ++GEP) {
        Instruction * I = *GEP;
        GetElementPtrInst * GEPI = dyn_cast<GetElementPtrInst>(I);
        handleGetElementPtr(GEPI);
      }
      continue;
    } else if (AllocaInst *AI = dyn_cast<AllocaInst>(iLocal)) {
      AllocaInst * AIOrig = AI;
      if (!DisableStackChecks) {
#ifndef LLVA_KERNEL      
        if (!equivPass->ContainsDSGraphFor(F)) {
          //some times the ECGraphs doesnt contain F
          //for newly created cloned functions
          PA::FuncInfo *FI = paPass->getFuncInfoOrClone(F);
          Value *temp = FI->MapValueToOriginal(AI);
          if (temp)
            AIOrig = dyn_cast<AllocaInst>(temp);
          else
            continue;
          assert(AIOrig && " Instruction not in value map (clone)\n");
        }
#endif       
        ++I;
        registerAllocaInst(AI, AIOrig);
        continue;
      }
    } else if (CallInst *CI = dyn_cast<CallInst>(iLocal)) {
      ++I;
      handleCallInst(CI);
      continue;
    }

    //
    // Move to the next instruction.
    //
    ++I;
  } 
}


void InsertPoolChecks::registerAllocaInst(AllocaInst *AI, AllocaInst *AIOrig) {
  //
  // Get the pool handle for the node that this contributes to...
  //
  Function *FOrig  = AIOrig->getParent()->getParent();
  DSNode *Node = getDSNode(AIOrig, FOrig);
  if (!Node) return;
  assert ((Node->isAllocaNode()) && "DSNode for alloca is missing stack flag!");

  //
  // Only register the stack allocation if it may be the subject of a run-time
  // check.  This can only occur when the object is used like an array because:
  //  1) GEP checks are only done when accessing arrays.
  //  2) Load/Store checks are only done on collapsed nodes (which appear to be
  //     used like arrays).
  //
  if (!(Node->isArray()))
    return;

  //
  // Determine if any use (direct or indirect) escapes this function.  If not,
  // then none of the checks will consult the MetaPool, and we can forego
  // registering the alloca.
  //
  bool MustRegisterAlloca = false;
  std::vector<Value *> AllocaWorkList;
  AllocaWorkList.push_back (AI);
  while ((!MustRegisterAlloca) && (AllocaWorkList.size())) {
    Value * V = AllocaWorkList.back();
    AllocaWorkList.pop_back();
    Value::use_iterator UI = V->use_begin();
    for (; UI != V->use_end(); ++UI) {
      // We cannot handle PHI nodes or Select instructions
      if (isa<PHINode>(UI) || isa<SelectInst>(UI)) {
        MustRegisterAlloca = true;
        continue;
      }

      // The pointer escapes if it's stored to memory somewhere.
      StoreInst * SI;
      if ((SI = dyn_cast<StoreInst>(UI)) && (SI->getOperand(0) == V)) {
        MustRegisterAlloca = true;
        continue;
      }

      // GEP instructions are okay, but need to be added to the worklist
      if (isa<GetElementPtrInst>(UI)) {
        AllocaWorkList.push_back (*UI);
        continue;
      }

      // Cast instructions are okay as long as they cast to another pointer
      // type
      if (CastInst * CI = dyn_cast<CastInst>(UI)) {
        if (isa<PointerType>(CI->getType())) {
          AllocaWorkList.push_back (*UI);
          continue;
        } else {
          MustRegisterAlloca = true;
          continue;
        }
      }

      if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(UI)) {
        if (cExpr->getOpcode() == Instruction::Cast) {
          AllocaWorkList.push_back (*UI);
          continue;
        } else {
          MustRegisterAlloca = true;
          continue;
        }
      }

      CallInst * CI1;
      if (CI1 = dyn_cast<CallInst>(UI)) {
        if (!(CI1->getCalledFunction())) {
          MustRegisterAlloca = true;
          continue;
        }

        std::string FuncName = CI1->getCalledFunction()->getName();
        if (FuncName == "exactcheck3") {
          AllocaWorkList.push_back (*UI);
          continue;
        } else if ((FuncName == "llvm.memcpy.i32")    || 
                   (FuncName == "llvm.memcpy.i64")    ||
                   (FuncName == "llvm.memset.i32")    ||
                   (FuncName == "llvm.memset.i64")    ||
                   (FuncName == "llvm.memmove.i32")   ||
                   (FuncName == "llvm.memmove.i64")   ||
                   (FuncName == "llva_memcpy")        ||
                   (FuncName == "llva_memset")        ||
                   (FuncName == "llva_strncpy")       ||
                   (FuncName == "llva_invokememcpy")  ||
                   (FuncName == "llva_invokestrncpy") ||
                   (FuncName == "llva_invokememset")  ||
                   (FuncName == "memcmp")) {
           continue;
        } else {
          MustRegisterAlloca = true;
          continue;
        }
      }
    }
  }

  if (!MustRegisterAlloca) {
    ++SavedRegAllocs;
    return;
  }

  //
  // Insert the alloca registration.
  //
  Value *PH = getPoolHandle(AIOrig, FOrig);
  if (PH == 0 || isa<ConstantPointerNull>(PH)) return;

  Value *AllocSize =
    ConstantInt::get(Type::UIntTy, TD->getTypeSize(AI->getAllocatedType()));
  
  if (AI->isArrayAllocation())
    AllocSize = BinaryOperator::create(Instruction::Mul, AllocSize,
                                       AI->getOperand(0), "sizetmp", AI);

  // Insert object registration at the end of allocas.
  Instruction *iptI = AI->getNext();
  if (AI->getParent() == (&(AI->getParent()->getParent()->getEntryBlock()))) {
    BasicBlock::iterator InsertPt = AI->getParent()->begin();
    while (&(*(InsertPt)) != AI)
      ++InsertPt;
    while (isa<AllocaInst>(InsertPt))
      ++InsertPt;
    iptI = InsertPt;
  }

  //
  // Insert a call to register the object.
  //
  Instruction *Casted = new CastInst(AI, PointerType::get(Type::SByteTy),
                                     AI->getName()+".casted", iptI);
  Value *CastedPH = new CastInst(PH,
                                 PointerType::get(Type::SByteTy),
                                 "allocph",Casted);
  new CallInst(StackRegister,
               make_vector(CastedPH, Casted, AllocSize,0),
               "", iptI);

  //
  // Insert a call to unregister the object whenever the function can exit.
  //
  for (Function::iterator BB = AI->getParent()->getParent()->begin();
                          BB != AI->getParent()->getParent()->end();
                          ++BB) {
    iptI = BB->getTerminator();
    if (isa<ReturnInst>(iptI) || isa<UnwindInst>(iptI))
      new CallInst(StackFree,
                   make_vector(CastedPH, Casted, 0),
                   "", iptI);
  }

  // Update statistics
  ++StackRegisters;
}

//
// Method: insertAlignmentCheck()
//
// Description:
//  Insert an alignment check for the specified value.
//
void
InsertPoolChecks::insertAlignmentCheck (LoadInst * LI) {
  // Get the function containing the load instruction
  Function * F = LI->getParent()->getParent();

  // Get the DSNode for the result of the load instruction.  If it is type
  // unknown, then no alignment check is needed.
  DSNode * LoadResultNode = getDSNode (LI,F);
  if (!(LoadResultNode && (!(LoadResultNode->isNodeCompletelyFolded())))) {
    return;
  }

  //
  // Get the pool handle for the node.
  //
  Value *PH = getPoolHandle(LI, F);
  if (!PH) return;

  //
  // If the node is incomplete or unknown, then only perform the check if
  // checks to incomplete or unknown are allowed.
  //
  Function * ThePoolCheckFunction = PoolCheckAlign;
  if ((LoadResultNode->isUnknownNode()) || (LoadResultNode->isIncomplete())) {
    if (EnableUnknownChecks) {
      ThePoolCheckFunction = PoolCheckAlignUI;
    } else {
      ++MissedIncompleteChecks;
      return;
    }
  }

  //
  // A check is needed.  Scan through the links of the DSNode of the load's
  // pointer operand; we need to determine the offset for the alignment check.
  //
  DSNode * Node = getDSNode (LI->getPointerOperand(), F);
  if (!Node) return;
  for (unsigned i = 0 ; i < Node->getNumLinks(); ++i) {
    DSNodeHandle & LinkNode = Node->getLink(i);
    if (LinkNode.getNode() == LoadResultNode) {
      // Insertion point for this check is *after* the load.
      Instruction * InsertPt = LI->getNext();

      // Create instructions to cast the checked pointer and the checked pool
      // into sbyte pointers.
      Value *CastVI  = castTo (LI, PointerType::get(Type::SByteTy), InsertPt);
      Value *CastPHI = castTo (PH, PointerType::get(Type::SByteTy), InsertPt);

      // Create the call to poolcheck
      std::vector<Value *> args(1,CastPHI);
      args.push_back(CastVI);
      args.push_back (ConstantInt::get(Type::UIntTy, LinkNode.getOffset()));
      new CallInst (PoolCheckAlign,args, "", InsertPt);

      // Update the statistics
      ++AlignLSChecks;

      break;
    }
  }
}

#ifdef LLVA_KERNEL
//
// Method: addLSChecks()
//
// Description:
//  Insert a poolcheck() into the code for a load or store instruction.
//
void InsertPoolChecks::addLSChecks(Value *V, Instruction *I, Function *F) {
  // Get the DSNode for the pointer to check
  DSNode * Node = getDSNode (V,F);

  //
  // Do not perform any checks if there is no DSNode, if the node is not folded,
  // or if the node is incomplete.
  //
  if (!(Node && Node->isNodeCompletelyFolded()))
    return;

  //
  // We will perform checks on incomplete or unknown nodes, but we must accept
  // the possibility that the object will not be found.
  //
  Function * ThePoolCheckFunction = PoolCheck;
  if ((Node->isUnknownNode()) || (Node->isIncomplete())) {
    if (EnableUnknownChecks) {
      ThePoolCheckFunction = PoolCheckUI;
    } else {
      ++MissedIncompleteChecks;
      return;
    }
  }

  //
  // This may be a load instruction that loads a pointer that:
  //  1) Points to a type known pool, and
  //  2) Loaded from a type unknown pool
  //
  // If this is the case, we need to perform an alignment check on the result
  // of the load.  Do that here.
  //
  if (LoadInst * LI = dyn_cast<LoadInst>(I)) {
    insertAlignmentCheck (LI);
  }

  //  
  // Do not perform a load/store check if the pointer used for this operation
  // has already been checked.
  //
  if (findCheckedPointer(V)) {
    ++SavedPoolChecks;
    return;
  }

  // Get the pool handle associated with this pointer.  If there is no pool
  // handle, use a NULL pointer value and let the runtime deal with it.
  Value *PH = getPoolHandle(V, F);

  if (!PH) {
    // Update the number of poolchecks that won't do anything
    ++NullChecks;

    // Update the stats on why there will be no check
    ++MissedNullChecks;

    // Don't bother to insert the NULL check unless the user requested it
    if (!EnableNullChecks)
      return;
    PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
  } else {
    // This will be a full check; update the stats.
    assert (isa<GlobalValue>(PH));
    ++FullChecks;
  }

  // Create instructions to cast the checked pointer and the checked pool
  // into sbyte pointers.
  Value *CastVI  = castTo (V, PointerType::get(Type::SByteTy), I);
  Value *CastPHI = castTo (PH, PointerType::get(Type::SByteTy), I);

  // Create the call to poolcheck
  std::vector<Value *> args(1,CastPHI);
  args.push_back(CastVI);
  new CallInst (ThePoolCheckFunction ,args, "", I);
}

void InsertPoolChecks::addLoadStoreChecks (Function & FR) {
  Function *F = &FR;
  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
    if (LoadInst *LI = dyn_cast<LoadInst>(&*I)) {
      Value *P = LI->getPointerOperand();
      addLSChecks(P, LI, F);
    } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I)) {
      Value *P = SI->getPointerOperand();
      addLSChecks(P, SI, F);
    } else if (CallInst * CI = dyn_cast<CallInst>(&*I)) {
      if (Function * CalledFunc = CI->getCalledFunction()) {
        if ((CalledFunc->getName() == "llva_atomic_compare_and_swap") ||
            (CalledFunc->getName() == "llva_atomic_cas_lw") ||
            (CalledFunc->getName() == "llva_atomic_cas_h") ||
            (CalledFunc->getName() == "llva_atomic_cas_b") ||
            (CalledFunc->getName() == "llva_atomic_fetch_add_store") ||
            (CalledFunc->getName() == "llva_atomic_and") ||
            (CalledFunc->getName() == "llva_atomic_or")) {
          Value * P = CI->getOperand(1);
          addLSChecks (P, CI, F);
        }
      }
    }
  }
}
#else

void InsertPoolChecks::addLSChecks(Value *Vnew, const Value *V, Instruction *I, Function *F) {

  PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
  Value *PH = getPoolHandle(V, F, *FI );
  DSNode* Node = getDSNode(V, F);
  if (!PH) {
    return;
  } else {
    if (PH && isa<ConstantPointerNull>(PH)) {
      //we have a collapsed/Unknown pool
      Value *PH = getPoolHandle(V, F, *FI, true); 

      if (dyn_cast<CallInst>(I)) {
	// GEt the globals list corresponding to the node
	return;
	std::vector<Function *> FuncList;
	Node->addFullFunctionList(FuncList);
	std::vector<Function *>::iterator flI= FuncList.begin(), flE = FuncList.end();
	unsigned num = FuncList.size();
	if (flI != flE) {
	  const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
	  Value *NumArg = ConstantInt::get(csiType, num);	
					 
	  CastInst *CastVI = 
	    new CastInst(Vnew, 
			 PointerType::get(Type::SByteTy), "casted", I);
	
	  std::vector<Value *> args(1, NumArg);
	  args.push_back(CastVI);
	  for (; flI != flE ; ++flI) {
	    Function *func = *flI;
	    CastInst *CastfuncI = 
	      new CastInst(func, 
			   PointerType::get(Type::SByteTy), "casted", I);
	    args.push_back(CastfuncI);
	  }
	  new CallInst(FunctionCheck, args,"", I);
	}
      } else {


	CastInst *CastVI = 
	  new CastInst(Vnew, 
		       PointerType::get(Type::SByteTy), "casted", I);
	CastInst *CastPHI = 
	  new CastInst(PH, 
		       PointerType::get(Type::SByteTy), "casted", I);
	std::vector<Value *> args(1,CastPHI);
	args.push_back(CastVI);
	
	new CallInst(PoolCheck,args,"", I);
      }
    }
  }
}


void InsertPoolChecks::addLoadStoreChecks(Module &M){
  Module::iterator mI = M.begin(), mE = M.end();
  for ( ; mI != mE; ++mI) {
    Function *F = mI;
    //here we check that we only do this on original functions
    //and not the cloned functions, the cloned functions may not have the
    //DSG
    bool isClonedFunc = false;
    if (paPass->getFuncInfo(*F))
      isClonedFunc = false;
    else
      isClonedFunc = true;
    Function *Forig = F;
    PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
    if (isClonedFunc) {
      Forig = paPass->getOrigFunctionFromClone(F);
    }
    //we got the original function

    for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
      if (LoadInst *LI = dyn_cast<LoadInst>(&*I)) {
	//we need to get the LI from the original function
	Value *P = LI->getPointerOperand();
	if (isClonedFunc) {
	  assert(FI->NewToOldValueMap.count(LI) && " not in the value map \n");
	  const LoadInst *temp = dyn_cast<LoadInst>(FI->NewToOldValueMap[LI]);
	  assert(temp && " Instruction  not there in the NewToOldValue map");
	  const Value *Ptr = temp->getPointerOperand();
	  addLSChecks(P, Ptr, LI, Forig);
	} else {
	  addLSChecks(P, P, LI, Forig);
	}
      } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I)) {
	Value *P = SI->getPointerOperand();
	if (isClonedFunc) {
	  assert(FI->NewToOldValueMap.count(SI) && " not in the value map \n");
	  const StoreInst *temp = dyn_cast<StoreInst>(FI->NewToOldValueMap[SI]);
	  assert(temp && " Instruction  not there in the NewToOldValue map");
	  const Value *Ptr = temp->getPointerOperand();
	  addLSChecks(P, Ptr, SI, Forig);
	} else {
	  addLSChecks(P, P, SI, Forig);
	}
      } else if (CallInst *CI = dyn_cast<CallInst>(&*I)) {
	Value *FunctionOp = CI->getOperand(0);
	if (!isa<Function>(FunctionOp)) {
	  if (isClonedFunc) {
	    assert(FI->NewToOldValueMap.count(CI) && " not in the value map \n");
	    const CallInst *temp = dyn_cast<CallInst>(FI->NewToOldValueMap[CI]);
	    assert(temp && " Instruction  not there in the NewToOldValue map");
	    const Value* FunctionOp1 = temp->getOperand(0);
	    addLSChecks(FunctionOp, FunctionOp1, CI, Forig);
	  } else {
	    addLSChecks(FunctionOp, FunctionOp, CI, Forig);
	  }
	}
      } 
    }
  }
}

#endif

DSNode* InsertPoolChecks::getDSNode(const Value *V, Function *F) {
#ifndef LLVA_KERNEL
  DSGraph &TDG = equivPass->getDSGraph(*F);
#else  
  DSGraph &TDG = TDPass->getDSGraph(*F);
#endif  
  DSNode *DSN = TDG.getNodeForValue((Value *)V).getNode();
  return DSN;
}

unsigned InsertPoolChecks::getDSNodeOffset(const Value *V, Function *F) {
#ifndef LLVA_KERNEL
  DSGraph &TDG = equivPass->getDSGraph(*F);
#else  
  DSGraph &TDG = TDPass->getDSGraph(*F);
#endif  
  return TDG.getNodeForValue((Value *)V).getOffset();
}
#ifndef LLVA_KERNEL
Value *InsertPoolChecks::getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed) {
  const DSNode *Node = getDSNode(V,F);
  // Get the pool handle for this DSNode...
  //  assert(!Node->isUnknownNode() && "Unknown node \n");
  Type *VoidPtrType = PointerType::get(Type::SByteTy); 
  Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
  Type *PoolDescPtrTy = PointerType::get(PoolDescType);
  if (!Node) {
    return 0; //0 means there is no isse with the value, otherwise there will be a callnode
  }
  if (Node->isUnknownNode()) {
    //FIXME this should be in a top down pass or propagated like collapsed pools below 
    if (!collapsed) {
      assert(!getDSNodeOffset(V, F) && " we don't handle middle of structs yet\n");
      return Constant::getNullValue(PoolDescPtrTy);
    }
  }
  std::map<const DSNode*, Value*>::iterator I = FI.PoolDescriptors.find(Node);
  map <Function *, set<Value *> > &
    CollapsedPoolPtrs = efPass->CollapsedPoolPtrs;
  
  if (I != FI.PoolDescriptors.end()) {
    // Check that the node pointed to by V in the TD DS graph is not
    // collapsed
    
    if (!collapsed && CollapsedPoolPtrs.count(F)) {
      Value *v = I->second;
      if (CollapsedPoolPtrs[F].find(I->second) !=
	  CollapsedPoolPtrs[F].end()) {
#ifdef DEBUG
	std::cerr << "Collapsed pools \n";
#endif
	return Constant::getNullValue(PoolDescPtrTy);
      } else {
	return v;
      }
    } else {
      return I->second;
    } 
  }
  return 0;
}
#else
Value *
InsertPoolChecks::getPoolHandle(const Value *V, Function *F) {
  DSGraph &TDG =  TDPass->getDSGraph(*F);
  DSNode *Node = TDG.getNodeForValue((Value *)V).getNode();

  // Register that we will need allocations with this DSNode registered.
  if (Node)
    PHNeeded.insert (Node);

  // Get the pool handle for this DSNode...
  //  assert(!Node->isUnknownNode() && "Unknown node \n");
  //  if (Node->isUnknownNode()) {
  //    return 0;
  //  }
  return getPD (Node, *F->getParent());
}
#endif
