diff --git a/llvm/lib/Analysis/DataStructure/FunctionRepBuilder.cpp b/llvm/lib/Analysis/DataStructure/FunctionRepBuilder.cpp
new file mode 100644
index 0000000..19c406c
--- /dev/null
+++ b/llvm/lib/Analysis/DataStructure/FunctionRepBuilder.cpp
@@ -0,0 +1,331 @@
+//===- FunctionRepBuilder.cpp - Build the datastructure graph for a method --===//
+//
+// 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->Nodes.push_back(N);
+      Rep->ValueMap[V].add(N);
+      Rep->addAllUsesToWorkList(GV);
+    }
+}
+
+
+// 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->Nodes.push_back(C);
+  Rep->CallMap[CI] = C;
+      
+  if (isa<PointerType>(CI->getType())) {
+    // Create a shadow node to represent the memory object that the return
+    // value points to...
+    ShadowDSNode *Shad = new ShadowDSNode(C, Func->getParent());
+    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) {
+  NewDSNode *N = new NewDSNode(AI);
+  Rep->Nodes.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 (isa<PointerType>((*I)->getType())) {
+      ArgDSNode *Arg = new ArgDSNode(*I);
+      Nodes.push_back(Arg);
+      
+      // Add a shadow value for it to represent what it is pointing
+      // to and add this to the value map...
+      ShadowDSNode *Shad = new ShadowDSNode(Arg, Func->getParent());
+      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 (Ptr.Node->NodeType == DSNode::ShadowNode) {
+      // 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 *Shad = (ShadowDSNode*)Ptr.Node;
+      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;
+        
+  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);
+  Nodes = Builder.getNodes();
+  ShadowNodes = Builder.getShadowNodes();
+  RetNode = Builder.getRetNode();
+  ValueMap = Builder.getValueMap();
+}
+
