diff --git a/llvm/.svnignore b/llvm/.svnignore
new file mode 100644
index 0000000000000000000000000000000000000000..52cf5b958f2d38c10c725ba9fd58d182ee54ffea
--- /dev/null
+++ b/llvm/.svnignore
@@ -0,0 +1,2 @@
+Debug+Asserts
+*.inc
diff --git a/llvm/include/llvm/BuildDFG/BuildDFG.h b/llvm/include/llvm/BuildDFG/BuildDFG.h
index 0d8bbbe2e6ed112cf9101a67311f823a8feafda8..c17f9ff743d937d70eca0895006d461c94b060b1 100644
--- a/llvm/include/llvm/BuildDFG/BuildDFG.h
+++ b/llvm/include/llvm/BuildDFG/BuildDFG.h
@@ -53,6 +53,7 @@ namespace builddfg {
     static bool isViscGraphIntrinsic(Instruction * I);
     static bool isViscQueryIntrinsic(Instruction* I);
     static bool isViscIntrinsic(Instruction* I);
+    static bool isTypeCongruent(Type *L, Type *R);
 
   //TODO: Maybe make these fields const
     DFInternalNode *getRoot();
diff --git a/llvm/include/llvm/IR/DFGraph.h b/llvm/include/llvm/IR/DFGraph.h
index d8fc6c96a7d10bc47ac7e3fa7bbec326b2f87a3a..ae0bcd4f40d88fdf1d4fa440af30071a09578dbd 100644
--- a/llvm/include/llvm/IR/DFGraph.h
+++ b/llvm/include/llvm/IR/DFGraph.h
@@ -26,6 +26,7 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/GraphWriter.h"
 
 
@@ -54,6 +55,7 @@ private:
   DFNodeListType ChildrenList;    ///< List of children Dataflow Nodes
   DFEdgeListType DFEdgeList;      ///< List of Dataflow edges among children
 
+
 public:
   DFGraph(DFInternalNode* P) {
     // ChildrenList.push_back(llvm::DFLeafNode::Create(NULL, NULL, NULL));
@@ -128,6 +130,13 @@ public:
 
 class DFNode {
 
+public:
+  // Discriminator for LLVM-style RTTI (dyn_cast et al.)
+  enum DFNodeKind {
+    InternalNode,
+    LeafNode
+  };
+
 private:
   typedef std::vector<DFNode*> DFNodeListType;
   typedef std::vector<DFEdge*> DFEdgeListType;
@@ -147,8 +156,10 @@ private:
   DFEdgeListType OutDFEdges;      ///< List of outgoing edges i.e.,
                                   ///< DFEdges originating from this DFNode to
                                   ///< successor DFNodes
+  Type* OutputType;               ///< Output Type
   int Level;                      ///< Distance to the top-level DFNode in the
                                   ///< hierarchy
+  const DFNodeKind Kind;          ///< Kind of Node Internal/Leaf
 
 public:
   // Iterators
@@ -213,13 +224,24 @@ public:
   //===--------------------------------------------------------------------===//
 
   // Functions
+
+  DFNodeKind getKind() const {
+    return Kind;
+  }
+
   DFNode(IntrinsicInst* _II, Function* _FuncPointer, DFNode* _Parent,
-         int _NumOfDim, std::vector<Value*> _DimLimits) : II(_II),
+         int _NumOfDim, std::vector<Value*> _DimLimits, DFNodeKind _K): II(_II),
          FuncPointer(_FuncPointer), Parent(_Parent), NumOfDim(_NumOfDim),
-         DimLimits(_DimLimits) {
+         DimLimits(_DimLimits), Kind(_K) {
+
+    OutputType = FuncPointer->getFunctionType()->getReturnType();
     Level = (_Parent) ? _Parent->getLevel() + 1 : 0 ;
   }
 
+  Type* getOutputType() {
+    return OutputType;
+  }
+
   void addSuccessor(DFNode* N) {
     Successors.push_back(N);
   }
@@ -259,14 +281,19 @@ public:
 class DFInternalNode : public DFNode {
 
 private:
-  DFGraph* childGraph;
+  DFGraph* childGraph;            ///< Pointer to dataflow graph
 
   // Constructor
   DFInternalNode(IntrinsicInst* II, Function* FuncPointer, DFNode* Parent,
                  int NumOfDim, std::vector<Value*> DimLimits) :
-                 DFNode(II, FuncPointer, Parent, NumOfDim, DimLimits) {
+                 DFNode(II, FuncPointer, Parent, NumOfDim, DimLimits,
+                 InternalNode) {
+
     childGraph = new DFGraph(this);
-    //childGraph->addChildDFNode(DFLeafNode::Create(NULL, NULL, this));
+
+    // Internal Node output type must always be a struct type.
+    assert(isa<StructType>(getOutputType())
+      && "Invalid return type of internal dataflow node");
   }
 public:
 
@@ -276,6 +303,10 @@ public:
     return new DFInternalNode(II, FuncPointer, Parent, NumOfDim, DimLimits);
   }
 
+  static bool classof(const DFNode *N) {
+    return N->getKind() == InternalNode;
+  }
+
   void addChildToDFGraph(DFNode* N) {
     childGraph->addChildDFNode(N);
   }
@@ -298,7 +329,7 @@ private:
   // Constructor
   DFLeafNode(IntrinsicInst* II, Function* FuncPointer, DFNode* Parent,
              int NumOfDim = 0, std::vector<Value*> DimLimits = std::vector<Value*>())
-            : DFNode(II, FuncPointer, Parent, NumOfDim, DimLimits) {}
+            : DFNode(II, FuncPointer, Parent, NumOfDim, DimLimits, LeafNode) {}
 
 public:
 
@@ -308,6 +339,10 @@ public:
     return new DFLeafNode(II, FuncPointer, Parent, NumOfDim, DimLimits);
   }
 
+  static bool classof(const DFNode *N) {
+    return N->getKind() == LeafNode;
+  }
+
   void applyDFNodeVisitor(DFNodeVisitor &V); /*virtual*/
 //  void applyDFEdgeVisitor(DFEdgeVisitor &V); /*virtual*/
 
@@ -463,7 +498,7 @@ public:
 //};
 */
 
-/*
+
 template <> struct GraphTraits<DFNode*> {
   typedef DFNode NodeType;
   typedef typename DFNode::successor_iterator ChildIteratorType;
@@ -511,16 +546,16 @@ struct DOTGraphTraits<DFGraph*> : public DefaultDOTGraphTraits {
     return N->getFuncPointer()->getName();
   }
 
-  void addCustomGraphFeatures(DFGraph* G, GraphWriter<DFGraph*> &GW) {
-    
+  static void addCustomGraphFeatures(DFGraph* G, GraphWriter<DFGraph*> &GW) {
+
   }
 };
 
-*/
+
 
 void viewDFGraph(DFGraph *G) {
-  //llvm::WriteGraph(G, "DataflowGrpah");
-  //llvm::ViewGraph(G, "DataflowGraph");
+  llvm::WriteGraph(G, "DataflowGrpah");
+  llvm::ViewGraph(G, "DataflowGraph");
 }
 
 
diff --git a/llvm/include/llvm/IR/IntrinsicsVISC.td b/llvm/include/llvm/IR/IntrinsicsVISC.td
index 8028525a38c4d858f9a512a60b5ca23758e9b283..3d78b189606b6675fc00fc48f56e8678c9ec2b8f 100644
--- a/llvm/include/llvm/IR/IntrinsicsVISC.td
+++ b/llvm/include/llvm/IR/IntrinsicsVISC.td
@@ -49,11 +49,11 @@ let TargetPrefix = "visc" in {
                                         []>;
 
   /* Create dataflow edge intrinsic -
-   * i8* llvm.visc.createEdge(i8*, i8*, function*, function*, instr*);
+   * i8* llvm.visc.createEdge(i8*, i8*, i1, i32, i32);
    */
   def int_visc_createEdge : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
-                                      llvm_i1_ty, llvm_i32_ty, llvm_i32_ty,
-                                      llvm_ptr_ty], []>;
+                                      llvm_i1_ty, llvm_i32_ty, llvm_i32_ty],
+                                      []>;
 
   /* Find associated dataflow node intrinsic -
    * i8* llvm.visc.getNode();
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index af86eb88788b2532dbb1120ba8084e429f6cf425..8ecb4f43457825e591b913fac1de630f18b36af0 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -222,7 +222,7 @@ uint64_t Type::getArrayNumElements() const {
 }
 
 unsigned Type::getVectorNumElements() const {
-  if (const SymVectorType *SVT = dyn_cast<SymVectorType>(this))
+  if (isa<SymVectorType>(this))
     return 4; // FIXME: This is just to avoid error in current case. Add assert here.
   return cast<VectorType>(this)->getNumElements();
 }
diff --git a/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp b/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp
index 0c9d907a0b0f3dcbe150e857fbc615edc2dc36ba..fbf30f87ac7e7bee2d445c326d9aee0fb17e645b 100644
--- a/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp
+++ b/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp
@@ -23,7 +23,7 @@ namespace builddfg {
 
   bool BuildDFG::runOnModule(Module &M) {
 
-    Function* f; // Root function, initialized later
+    Function* F; // Root function, initialized later
     bool foundRootFunction = false;
 
     // Loop over all of the global variables
@@ -36,7 +36,7 @@ namespace builddfg {
       if((i->getName()).equals("llvm.visc.root")) {
         errs() << "----------- Found Root Function -------------\n\n";
         foundRootFunction = true;
-        f = cast<Function>(i->getOperand(0));
+        F = cast<Function>(i->getOperand(0));
       }
     }
 
@@ -44,7 +44,7 @@ namespace builddfg {
 
     // Root function has been initialized from this point on.
 
-    errs() << "-------- Searching for launch site ----------\n";
+    /*errs() << "-------- Searching for launch site ----------\n";
 
     bool foundLaunchSite = false;
     IntrinsicInst* II;
@@ -63,8 +63,8 @@ namespace builddfg {
 
     // Intrinsic Instruction has been initialized from this point on.
 
-    Function* F = cast<Function>((II->getOperand(0))->stripPointerCasts());
-    Root = DFInternalNode::Create(II, F);
+    Function* F = cast<Function>((II->getOperand(0))->stripPointerCasts());*/
+    Root = DFInternalNode::Create(NULL, F);
     BuildGraph(Root, F);
 
     viewDFGraph(Root->getChildGraph());
@@ -130,6 +130,18 @@ namespace builddfg {
     return false;
   }
 
+  // Two types are "congruent" if they are identical, or if they are both
+  // pointer types with different pointee types and the same address space.
+  bool BuildDFG::isTypeCongruent(Type* L, Type* R) {
+    if(L == R)
+      return true;
+    PointerType *PL = dyn_cast<PointerType>(L);
+    PointerType *PR = dyn_cast<PointerType>(R);
+    if (!PL || !PR)
+      return false;
+    return PL->getAddressSpace() == PR->getAddressSpace();
+  }
+
   // Handles all the createNodeXX visc intrinsics.
   void BuildDFG::handleCreateNode(DFInternalNode* N, IntrinsicInst* II) {
     bool isInternalNode = false;
@@ -182,20 +194,42 @@ namespace builddfg {
 
     bool EdgeType = !cast<ConstantInt>(II->getOperand(2))->isZero();
 
-    int SourcePosition =
-      (int) cast<ConstantInt>(II->getOperand(3))->getSExtValue();
-    int DestPosition =
-      (int) cast<ConstantInt>(II->getOperand(4))->getSExtValue();
+    unsigned int SourcePosition = cast<ConstantInt>(II->getOperand(3))->getZExtValue();
+    unsigned int DestPosition = cast<ConstantInt>(II->getOperand(4))->getZExtValue();
+
+    Type *SrcTy, *DestTy;
+
+    // Get destination type
+    FunctionType *FT = DestDF->getFuncPointer()->getFunctionType();
+    assert((FT->getNumParams() > DestPosition) 
+      && "Invalid argument number for destination dataflow node!");
+    DestTy = FT->getParamType(DestPosition);
+  
+    // Get source type
+    if(isa<DFInternalNode>(SrcDF)) { 
+      // For Internal node, get the correct element type from the struct type
+      StructType* OutTy = cast<StructType>(SrcDF->getOutputType());
+      assert((OutTy->getNumElements() > SourcePosition)
+        && "Invalid argument number for source dataflow node!");
+      SrcTy = OutTy->getElementType(SourcePosition);
+    }
+    else {
+      // For Leaf node, there is just one outgoing edge
+      assert((SourcePosition == 0)
+        && "Invalid argument number for source dataflow node!");
+      SrcTy = SrcDF->getOutputType();
+    }
 
-    BitCastInst* BitCastI = cast<BitCastInst>((II->getOperand(5))->stripPointerCasts());
-    Type* ArgType = BitCastI->getOperand(0)->getType();
+    // check if the types are compatible
+    assert(isTypeCongruent(SrcTy, DestTy)
+      && "Source and destination type of edge do not match");
 
     DFEdge* newDFEdge = DFEdge::Create(SrcDF,
                                        DestDF,
                                        EdgeType,
                                        SourcePosition,
                                        DestPosition,
-                                       ArgType);
+                                       DestTy);
 
     HandleToDFEdgeMap[II] = newDFEdge;
 
diff --git a/llvm/lib/Transforms/BuildDFG/Makefile b/llvm/lib/Transforms/BuildDFG/Makefile
index a1a9f46b9aa813533bd72ee8a0c4f0fec23e103f..870df19c30eaafd0471ebfcc5f45999cba93c0ed 100644
--- a/llvm/lib/Transforms/BuildDFG/Makefile
+++ b/llvm/lib/Transforms/BuildDFG/Makefile
@@ -9,7 +9,7 @@
 
 LEVEL = ../../../
 LIBRARYNAME = LLVMBuildDFG
-#LOADABLE_MODULE = 1
+LOADABLE_MODULE = 1
 #SHARED_LIBRARY = 1
 #BUILD_ARCHIVE = 1
 #USEDLIBS =
diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/CMakeLists.txt b/llvm/lib/Transforms/DFG2LLVM_X86/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..70c3b1ddb1ba135359bf5552e344e756fb22216e
--- /dev/null
+++ b/llvm/lib/Transforms/DFG2LLVM_X86/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_llvm_loadable_module( LLVMBuildDFG
+  DFG2LLVM_X86.cpp
+  )
diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee93bb926380dab7854dfc4da5bda20ca8c026fb
--- /dev/null
+++ b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
@@ -0,0 +1,342 @@
+//=== DFG2LLVM_X86.cpp ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "DFG2LLVM_X86"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/InstIterator.h"
+
+#include "llvm/BuildDFG/BuildDFG.h"
+
+using namespace llvm;
+using namespace builddfg;
+
+//STATISTIC(IntrinsicCounter, "Counts number of visc intrinsics greeted");
+
+namespace {
+  // DFG2LLVM_X86 - The first implementation.
+  struct DFG2LLVM_X86 : public ModulePass {
+    static char ID; // Pass identification, replacement for typeid
+    DFG2LLVM_X86() : ModulePass(ID) {}
+
+    private:
+    // Member variables
+
+    // Functions
+
+    public:
+    bool runOnModule(Module &M);
+
+    void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<BuildDFG>();
+    }
+
+
+  };
+
+  // Visitor for Code generation traversal (tree traversal for now)
+  class CodeGenTraversal : public DFNodeVisitor {
+
+  private:
+    //Member variables
+    Module &M;
+    BuildDFG &DFG;
+
+    //Functions
+    void codeGen(DFInternalNode* N);
+    void codeGen(DFLeafNode* N);
+  public:
+    // Constructor
+    CodeGenTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) { }
+
+    virtual void visit(DFInternalNode* N) {
+      errs() << "Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n";
+      codeGen(N);
+      errs() << "DONE" << "\n";
+      for(DFGraph::children_iterator i = N->getChildGraph()->begin(),
+          e = N->getChildGraph()->end(); i != e; ++i) {
+        DFNode* child = *i;
+        child->applyDFNodeVisitor(*this);
+      }
+    }
+
+    virtual void visit(DFLeafNode* N) {
+      errs() << "Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n";
+      codeGen(N);
+      errs() << "DONE" << "\n";
+    }
+
+  };
+
+  class SuccessorTraversal : public DFNodeVisitor {
+
+  private:
+    // Member Variables
+    // Functions
+  public:
+    // Constructor
+    SuccessorTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) {}
+
+    virtual void visit(DFInternalNode* N) {
+    errs() << "Visited Node (I) - " << N->getFuncPointer()->getName() << "\n";
+    for(DFInternalNode::successor_iterator i = N->successors_begin(),
+        e = N->successors_end(); i != e; ++i) {
+      /* Traverse the graph.
+       * Choose the kind of traversal we want
+       * Do we do a DAG kind of traversal?
+       */
+      }
+    }
+
+    virtual void visit(DFLeafNode* N) {
+      errs() << "Visited Node (L) - " << N->getFuncPointer()->getName() << "\n";
+    }
+
+  };
+
+  bool DFG2LLVM_X86::runOnModule(Module &M) {
+
+    // Get the BuildDFG Analysis Results:
+    // - Dataflow graph
+    // - Maps from i8* hansles to DFNode and DFEdge
+    BuildDFG &DFG = getAnalysis<BuildDFG>();
+
+    DFInternalNode *Root = DFG.getRoot();
+//    BuildDFG::HandleToDFNode &HandleToDFNodeMap = DFG.getHandleToDFNodeMap();
+//    BuildDFG::HandleToDFEdge &HandleToDFEdgeMap = DFG.getHandleToDFEdgeMap();
+
+    // Visitor for Code Generation Graph Traversal
+    CodeGenTraversal *CGTVisitor = new CodeGenTraversal(M, DFG);
+
+    // Initiate code generation for root DFNode
+    CGTVisitor->visit(Root);
+
+    return true;
+  }
+
+  void CodeGenTraversal::codeGen(DFInternalNode* N) {
+    std::vector<IntrinsicInst*> IItoRemove;
+    std::vector<std::pair<IntrinsicInst*, Value*>> IITtoReplace;
+
+
+  }
+
+  // Code generation for leaf nodes
+  void CodeGenTraversal::codeGen(DFLeafNode* N) {
+
+    std::vector<IntrinsicInst *> IItoRemove;
+    std::vector<std::pair<IntrinsicInst *, Value *> > IItoReplace;
+    BuildDFG::HandleToDFNode Leaf_HandleToDFNodeMap;
+
+    // Get the function associated woth the dataflow node
+    Function *F = N->getFuncPointer();
+
+    // Go through all the instructions
+    for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
+      Instruction *I = &(*i);
+      // Leaf nodes should not contain VISC graph intrinsics or launch
+      assert(!BuildDFG::isViscLaunchIntrinsic(I) && "Launch intrinsic within a dataflow graph!");
+      assert(!BuildDFG::isViscGraphIntrinsic(I) && "VISC graph intrinsic within a leaf dataflow node!");
+
+      if (BuildDFG::isViscQueryIntrinsic(I)) {
+        IntrinsicInst* II = cast<IntrinsicInst>(I);
+        IntrinsicInst* ArgII;
+        DFNode* ArgDFNode;
+
+/******************************************************************************
+*                        Handle VISC Query intrinsics                        *
+******************************************************************************/
+        switch (II->getIntrinsicID()) {
+/**************************** llvm.visc.getNode() *****************************/
+          case Intrinsic::visc_getNode: {
+            // add mapping <intrinsic, this node> to the node-specific map
+            Leaf_HandleToDFNodeMap[II] = N;
+            IItoRemove.push_back(II);
+            }
+            break;
+/************************* llvm.visc.getParentNode() **************************/
+          case Intrinsic::visc_getParentNode: {
+            // get the parent node of the arg node
+            // get argument node
+            ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
+            // get the parent node of the arg node
+            ArgDFNode = Leaf_HandleToDFNodeMap[ArgII];
+            // Add mapping <intrinsic, parent node> to the node-specific map
+            // the argument node must have been added to the map, orelse the
+            // code could not refer to it
+            Leaf_HandleToDFNodeMap[II] = ArgDFNode->getParent();
+            IItoRemove.push_back(II);
+            }
+            break;
+/*************************** llvm.visc.getNumDims() ***************************/
+          case Intrinsic::visc_getNumDims: {
+            // get node from map
+            // get the appropriate field
+            ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
+            int numOfDim = Leaf_HandleToDFNodeMap[ArgII]->getNumOfDim();
+            IntegerType* IntTy = Type::getInt32Ty(getGlobalContext());
+            ConstantInt* numOfDimConstant = ConstantInt::getSigned(IntTy, (int64_t) numOfDim);
+
+            IItoReplace.push_back(std::make_pair(II,numOfDimConstant));
+            }
+            break;
+/*********************** llvm.visc.getNodeInstanceID() ************************/
+          case Intrinsic::visc_getNodeInstanceID: {
+            ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
+            ArgDFNode = Leaf_HandleToDFNodeMap[ArgII];
+            // A leaf node always has a parent
+            DFNode* ParentDFNode = DFG.getHandleToDFNodeMap()[ArgII];
+
+            // Get specified dimension
+            // (dim = 0) => x
+            // (dim = 1) => y
+            // (dim = 2) => z
+            ConstantInt * DimConstant = cast<ConstantInt>(II->getOperand(1));
+            int dim = (int) DimConstant->getSExtValue();
+            assert((dim >= 0) && (dim < 3) && "Invalid dimension argument");
+
+            // Argument of the function to be called
+            ArrayRef<Value *> Args(DimConstant);
+
+            // The following is to find which function to call
+            Function * OpenCLFunction;
+            int parentLevel = ParentDFNode->getLevel();
+
+            if (!parentLevel) {
+            // We only have one level in the hierarchy, but still need to
+            // specify a global id
+              assert((dim != 2) && "Invalid dimension argument");
+
+              FunctionType* FT =
+                FunctionType::get(Type::getInt32Ty(getGlobalContext()),
+                                  std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
+                                  false);
+              OpenCLFunction = cast<Function>
+                (M.getOrInsertFunction(StringRef("get_global_id"), FT));
+            } else if (Leaf_HandleToDFNodeMap[ArgII] == Leaf_HandleToDFNodeMap[II]) {
+              // We are asking for this node's id with respect to its parent
+              // this is a local id call
+              FunctionType* FT =
+                FunctionType::get(Type::getInt32Ty(getGlobalContext()),
+                                  std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
+                                  false);
+              OpenCLFunction = cast<Function>
+                (M.getOrInsertFunction(StringRef("get_local_id"), FT));
+            } else if (Leaf_HandleToDFNodeMap[ArgII] == N->getParent()) {
+              // We are asking for this node's parent's id with respect to its
+              // parent: this is a group id call
+              FunctionType* FT =
+                FunctionType::get(Type::getInt32Ty(getGlobalContext()),
+                                  std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
+                                  false);
+              OpenCLFunction = cast<Function>
+                (M.getOrInsertFunction(StringRef("get_group_id"), FT));
+            } else {
+              assert(false && "Unable to translate this intrinsic");
+            }
+
+            CallInst* CI = CallInst::Create(OpenCLFunction, Args);
+            IItoReplace.push_back(std::make_pair(II,CI));
+            }
+            break;
+/********************** llvm.visc.getNumNodeInstances() ***********************/
+          case Intrinsic::visc_getNumNodeInstances: {
+
+//TODO: think about whether this is the best way to go
+// there are hw specific registers. therefore it is good to have the intrinsic
+// but then, why do we need to keep that info in the graph?
+// (only for the kernel configuration during the call)
+
+            ArgII = cast<IntrinsicInst>((II->getOperand(0))->stripPointerCasts());
+            ArgDFNode = Leaf_HandleToDFNodeMap[ArgII];
+            // A leaf node always has a parent
+            DFNode* ParentDFNode = DFG.getHandleToDFNodeMap()[ArgII];
+
+            // Get specified dimension
+            ConstantInt * DimConstant = cast<ConstantInt>(II->getOperand(1));
+            int dim = (int) DimConstant->getSExtValue();
+            assert((dim >= 0) && (dim < 3) && "Invalid dimension argument");
+
+            // Argument of the function to be called
+            ArrayRef<Value *> Args(DimConstant);
+
+            // The following is to find which function to call
+            Function * OpenCLFunction;
+            int parentLevel = ParentDFNode->getLevel();
+
+            if (!parentLevel) {
+            // We only have one level in the hierarchy, thus the node
+            // instances are global_size (gridDim x blockDim)
+              FunctionType* FT =
+                FunctionType::get(Type::getInt32Ty(getGlobalContext()),
+                                  std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
+                                  false);
+              OpenCLFunction = cast<Function>
+                (M.getOrInsertFunction(StringRef("get_global_size"), FT));
+            } else if (Leaf_HandleToDFNodeMap[ArgII] == Leaf_HandleToDFNodeMap[II]) {
+              // We are asking for this node's instances
+              // this is a local size (block dim) call
+              FunctionType* FT =
+                FunctionType::get(Type::getInt32Ty(getGlobalContext()),
+                                  std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
+                                  false);
+              OpenCLFunction = cast<Function>
+                (M.getOrInsertFunction(StringRef("get_local_size"), FT));
+            } else if (Leaf_HandleToDFNodeMap[ArgII] == N->getParent()) {
+              // We are asking for this node's parent's instances
+              // this is a (global_size/local_size) (grid dim) call
+              FunctionType* FT =
+                FunctionType::get(Type::getInt32Ty(getGlobalContext()),
+                                  std::vector<Type*>(1, Type::getInt32Ty(getGlobalContext())),
+                                  false);
+              OpenCLFunction = cast<Function>
+                (M.getOrInsertFunction(StringRef("get_num_groups"), FT));
+            } else {
+              assert(false && "Unable to translate this intrinsic");
+            }
+
+            CallInst* CI = CallInst::Create(OpenCLFunction, Args);
+            IItoReplace.push_back(std::make_pair(II,CI));
+            }
+            break;
+          default:
+            assert(false && "Unknown VISC Intrinsic!");
+            break;
+        }
+
+      } else {
+        //TODO: how to handle address space qualifiers in load/store
+      }
+
+    }
+
+    //TODO:
+    // When to replace the uses?
+    // In which order is it safe to replace the instructions in
+    // IItoReplace?
+    // Probably in the reverse order in the vectors
+    // It is a good idea to have them in one vector and chech the type
+    // using dyn_cast in order to determine if we replace with inst or value
+
+
+    //TODO: maybe leave these instructions to be removed by a later DCE pass
+    for (std::vector<IntrinsicInst *>::iterator i = IItoRemove.begin();
+         i != IItoRemove.end(); ++i)
+      (*i)->eraseFromParent();
+
+  }
+
+} // End of namespace
+
+char DFG2LLVM_X86::ID = 0;
+static RegisterPass<DFG2LLVM_X86> X("DFG2LLVM_X86",
+                                "Dataflow Graph to LLVM for X86 backend",
+                                false /* does not modify the CFG */,
+                                true /* transformation, not just analysis */);
+
diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.exports b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.exports
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/Makefile b/llvm/lib/Transforms/DFG2LLVM_X86/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0451d134d6bbb870704a0c1b004810cb58bce61c
--- /dev/null
+++ b/llvm/lib/Transforms/DFG2LLVM_X86/Makefile
@@ -0,0 +1,17 @@
+##===- lib/Transforms/BuildDFG/Makefile -----------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../
+LIBRARYNAME = LLVMDFG2LLVM_X86
+#LOADABLE_MODULE = 1
+#SHARED_LIBRARY = 1
+BUILD_ARCHIVE = 1
+#USEDLIBS =
+
+include $(LEVEL)/Makefile.common