//===- FunctionRepBuilder.cpp - Build the local datastructure graph -------===//
//
// Build the local datastructure graph for a single method.
//
//===----------------------------------------------------------------------===//

#include "FunctionRepBuilder.h"
#include "llvm/Function.h"
#include "llvm/iMemory.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/iTerminators.h"
#include "llvm/DerivedTypes.h"
#include "Support/STLExtras.h"
#include <algorithm>

// synthesizeNode - Create a new shadow node that is to be linked into this
// chain..
// FIXME: This should not take a FunctionRepBuilder as an argument!
//
ShadowDSNode *ShadowDSNode::synthesizeNode(const Type *Ty,
                                           FunctionRepBuilder *Rep) {
  // If we are a derived shadow node, defer to our parent to synthesize the node
  if (ShadowParent) return ShadowParent->synthesizeNode(Ty, Rep);

  // See if we have already synthesized a node of this type...
  for (unsigned i = 0, e = SynthNodes.size(); i != e; ++i)
    if (SynthNodes[i].first == Ty) return SynthNodes[i].second;

  // No we haven't.  Do so now and add it to our list of saved nodes...
  ShadowDSNode *SN = new ShadowDSNode(Ty, Mod, this);
  SynthNodes.push_back(make_pair(Ty, SN));
  Rep->addShadowNode(SN);
  return SN;
}




// visitOperand - If the specified instruction operand is a global value, add
// a node for it...
//
void InitVisitor::visitOperand(Value *V) {
  if (!Rep->ValueMap.count(V))                  // Only process it once...
    if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
      GlobalDSNode *N = new GlobalDSNode(GV);
      Rep->GlobalNodes.push_back(N);
      Rep->ValueMap[V].add(N);
      Rep->addAllUsesToWorkList(GV);

      // FIXME: If the global variable has fields, we should add critical
      // shadow nodes to represent them!
    }
}


// visitCallInst - Create a call node for the callinst, and create as shadow
// node if the call returns a pointer value.  Check to see if the call node
// uses any global variables...
//
void InitVisitor::visitCallInst(CallInst *CI) {
  CallDSNode *C = new CallDSNode(CI);
  Rep->CallNodes.push_back(C);
  Rep->CallMap[CI] = C;
      
  if (PointerType *PT = dyn_cast<PointerType>(CI->getType())) {
    // Create a critical shadow node to represent the memory object that the
    // return value points to...
    ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(),
                                          Func->getParent(), true);
    Rep->ShadowNodes.push_back(Shad);
    
    // The return value of the function is a pointer to the shadow value
    // just created...
    //
    C->getLink(0).add(Shad);

    // The call instruction returns a pointer to the shadow block...
    Rep->ValueMap[CI].add(Shad, CI);
    
    // If the call returns a value with pointer type, add all of the users
    // of the call instruction to the work list...
    Rep->addAllUsesToWorkList(CI);
  }

  // Loop over all of the operands of the call instruction (except the first
  // one), to look for global variable references...
  //
  for_each(CI->op_begin()+1, CI->op_end(),   // Skip first arg
           bind_obj(this, &InitVisitor::visitOperand));
}


// visitAllocationInst - Create an allocation node for the allocation.  Since
// allocation instructions do not take pointer arguments, they cannot refer to
// global vars...
//
void InitVisitor::visitAllocationInst(AllocationInst *AI) {
  AllocDSNode *N = new AllocDSNode(AI);
  Rep->AllocNodes.push_back(N);
  
  Rep->ValueMap[AI].add(N, AI);
  
  // Add all of the users of the malloc instruction to the work list...
  Rep->addAllUsesToWorkList(AI);
}


// Visit all other instruction types.  Here we just scan, looking for uses of
// global variables...
//
void InitVisitor::visitInstruction(Instruction *I) {
  for_each(I->op_begin(), I->op_end(),
           bind_obj(this, &InitVisitor::visitOperand));
}


// addAllUsesToWorkList - Add all of the instructions users of the specified
// value to the work list for further processing...
//
void FunctionRepBuilder::addAllUsesToWorkList(Value *V) {
  //cerr << "Adding all uses of " << V << "\n";
  for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
    Instruction *Inst = cast<Instruction>(*I);
    // When processing global values, it's possible that the instructions on
    // the use list are not all in this method.  Only add the instructions
    // that _are_ in this method.
    //
    if (Inst->getParent()->getParent() == F->getFunction())
      // Only let an instruction occur on the work list once...
      if (std::find(WorkList.begin(), WorkList.end(), Inst) == WorkList.end())
        WorkList.push_back(Inst);
  }
}




void FunctionRepBuilder::initializeWorkList(Function *Func) {
  // Add all of the arguments to the method to the graph and add all users to
  // the worklists...
  //
  for (Function::ArgumentListType::iterator I = Func->getArgumentList().begin(),
         E = Func->getArgumentList().end(); I != E; ++I)
    // Only process arguments that are of pointer type...
    if (PointerType *PT = dyn_cast<PointerType>((*I)->getType())) {
      ArgDSNode *Arg = new ArgDSNode(*I);
      ArgNodes.push_back(Arg);
      
      // Add a critical shadow value for it to represent what it is pointing
      // to and add this to the value map...
      ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(),
                                            Func->getParent(), true);
      ShadowNodes.push_back(Shad);
      ValueMap[*I].add(PointerVal(Shad), *I);
      
      // The value of the argument is the shadow value...
      Arg->getLink(0).add(Shad);
      
      // Make sure that all users of the argument are processed...
      addAllUsesToWorkList(*I);
    }
  
  // Iterate over the instructions in the method.  Create nodes for malloc and
  // call instructions.  Add all uses of these to the worklist of instructions
  // to process.
  //
  InitVisitor IV(this, Func);
  IV.visit(Func);
}




PointerVal FunctionRepBuilder::getIndexedPointerDest(const PointerVal &InP,
                                                     const MemAccessInst *MAI) {
  unsigned Index = InP.Index;
  const Type *SrcTy = MAI->getPointerOperand()->getType();

  for (MemAccessInst::const_op_iterator I = MAI->idx_begin(),
         E = MAI->idx_end(); I != E; ++I)
    if ((*I)->getType() == Type::UByteTy) {     // Look for struct indices...
      StructType *STy = cast<StructType>(SrcTy);
      unsigned StructIdx = cast<ConstantUInt>(*I)->getValue();
      for (unsigned i = 0; i != StructIdx; ++i)
        Index += countPointerFields(STy->getContainedType(i));

      // Advance SrcTy to be the new element type...
      SrcTy = STy->getContainedType(StructIdx);
    } else {
      // Otherwise, stepping into array or initial pointer, just increment type
      SrcTy = cast<SequentialType>(SrcTy)->getElementType();
    }
  
  return PointerVal(InP.Node, Index);
}

static PointerValSet &getField(const PointerVal &DestPtr) {
  assert(DestPtr.Node != 0);

  return DestPtr.Node->getLink(DestPtr.Index);
}


// Reprocessing a GEP instruction is the result of the pointer operand
// changing.  This means that the set of possible values for the GEP
// needs to be expanded.
//
void FunctionRepBuilder::visitGetElementPtrInst(GetElementPtrInst *GEP) {
  PointerValSet &GEPPVS = ValueMap[GEP];   // PointerValSet to expand
      
  // Get the input pointer val set...
  const PointerValSet &SrcPVS = ValueMap[GEP->getOperand(0)];
      
  bool Changed = false;  // Process each input value... propogating it.
  for (unsigned i = 0, e = SrcPVS.size(); i != e; ++i) {
    // Calculate where the resulting pointer would point based on an
    // input of 'Val' as the pointer type... and add it to our outgoing
    // value set.  Keep track of whether or not we actually changed
    // anything.
    //
    Changed |= GEPPVS.add(getIndexedPointerDest(SrcPVS[i], GEP));
  }

  // If our current value set changed, notify all of the users of our
  // value.
  //
  if (Changed) addAllUsesToWorkList(GEP);        
}

void FunctionRepBuilder::visitReturnInst(ReturnInst *RI) {
  RetNode.add(ValueMap[RI->getOperand(0)]);
}

void FunctionRepBuilder::visitLoadInst(LoadInst *LI) {
  // Only loads that return pointers are interesting...
  if (!isa<PointerType>(LI->getType())) return;
  const PointerType *DestTy = cast<PointerType>(LI->getType());

  const PointerValSet &SrcPVS = ValueMap[LI->getOperand(0)];        
  PointerValSet &LIPVS = ValueMap[LI];

  bool Changed = false;
  for (unsigned si = 0, se = SrcPVS.size(); si != se; ++si) {
    PointerVal Ptr = getIndexedPointerDest(SrcPVS[si], LI);
    PointerValSet &Field = getField(Ptr);

    if (Field.size()) {             // Field loaded wasn't null?
      Changed |= LIPVS.add(Field);
    } else if (ShadowDSNode *Shad = dyn_cast<ShadowDSNode>(Ptr.Node)) {
      // If we are loading a null field out of a shadow node, we need to
      // synthesize a new shadow node and link it in...
      //
      ShadowDSNode *SynthNode =
        Shad->synthesizeNode(DestTy->getElementType(), this);
      Field.add(SynthNode);

      Changed |= LIPVS.add(Field);
    }
  }

  if (Changed) addAllUsesToWorkList(LI);
}

void FunctionRepBuilder::visitStoreInst(StoreInst *SI) {
  // The only stores that are interesting are stores the store pointers
  // into data structures...
  //
  if (!isa<PointerType>(SI->getOperand(0)->getType())) return;
  if (!ValueMap.count(SI->getOperand(0))) return;  // Src scalar has no values!
        
  const PointerValSet &SrcPVS = ValueMap[SI->getOperand(0)];
  const PointerValSet &PtrPVS = ValueMap[SI->getOperand(1)];

  for (unsigned si = 0, se = SrcPVS.size(); si != se; ++si) {
    const PointerVal &SrcPtr = SrcPVS[si];
    for (unsigned pi = 0, pe = PtrPVS.size(); pi != pe; ++pi) {
      PointerVal Dest = getIndexedPointerDest(PtrPVS[pi], SI);

#if 0
      cerr << "Setting Dest:\n";
      Dest.print(cerr);
      cerr << "to point to Src:\n";
      SrcPtr.print(cerr);
#endif

      // Add SrcPtr into the Dest field...
      if (getField(Dest).add(SrcPtr)) {
        // If we modified the dest field, then invalidate everyone that points
        // to Dest.
        const std::vector<Value*> &Ptrs = Dest.Node->getPointers();
        for (unsigned i = 0, e = Ptrs.size(); i != e; ++i)
          addAllUsesToWorkList(Ptrs[i]);
      }
    }
  }
}

void FunctionRepBuilder::visitCallInst(CallInst *CI) {
  CallDSNode *DSN = CallMap[CI];
   
  unsigned PtrNum = 0, i = 0;
  if (isa<Function>(CI->getOperand(0)))
    ++i;          // Not an Indirect function call? Skip the function pointer...

  for (unsigned e = CI->getNumOperands(); i != e; ++i)
    if (isa<PointerType>(CI->getOperand(i)->getType()))
      DSN->addArgValue(PtrNum++, ValueMap[CI->getOperand(i)]);
}

void FunctionRepBuilder::visitPHINode(PHINode *PN) {
  assert(isa<PointerType>(PN->getType()) && "Should only update ptr phis");

  PointerValSet &PN_PVS = ValueMap[PN];
  bool Changed = false;
  for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
    Changed |= PN_PVS.add(ValueMap[PN->getIncomingValue(i)],
                          PN->getIncomingValue(i));

  if (Changed) addAllUsesToWorkList(PN);
}




// FunctionDSGraph constructor - Perform the global analysis to determine
// what the data structure usage behavior or a method looks like.
//
FunctionDSGraph::FunctionDSGraph(Function *F) : Func(F) {
  FunctionRepBuilder Builder(this);
  ArgNodes    = Builder.getArgNodes();
  AllocNodes  = Builder.getAllocNodes();
  ShadowNodes = Builder.getShadowNodes();
  GlobalNodes = Builder.getGlobalNodes();
  CallNodes   = Builder.getCallNodes();
  RetNode     = Builder.getRetNode();
  ValueMap    = Builder.getValueMap();

  bool Changed = true;
  while (Changed) {
    // Eliminate shadow nodes that are not distinguishable from some other
    // node in the graph...
    //
    Changed = UnlinkUndistinguishableNodes();

    // Eliminate shadow nodes that are now extraneous due to linking...
    Changed |= RemoveUnreachableNodes();
  }
}

