From ddef1bb056c1fc6806aa0d8f1655795bd7bb5ab7 Mon Sep 17 00:00:00 2001
From: Prakalp Srivastava <prakalps@gmail.com>
Date: Sat, 1 Aug 2015 18:38:08 -0500
Subject: [PATCH] Created Abstract class DFG2LLVM. The two passes
 DFG2LLVM_NVPTX and DFG2LLVM_X86 inherit from this class. Common
 features/functions have been put in the abstract class DFG2LLVM

---
 llvm/include/llvm/SupportVISC/DFG2LLVM.h      | 234 +++++++++++
 .../DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp         | 372 +++---------------
 .../Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp  | 242 ++----------
 3 files changed, 316 insertions(+), 532 deletions(-)
 create mode 100644 llvm/include/llvm/SupportVISC/DFG2LLVM.h

diff --git a/llvm/include/llvm/SupportVISC/DFG2LLVM.h b/llvm/include/llvm/SupportVISC/DFG2LLVM.h
new file mode 100644
index 0000000000..6f2aa5d02b
--- /dev/null
+++ b/llvm/include/llvm/SupportVISC/DFG2LLVM.h
@@ -0,0 +1,234 @@
+
+//===---- DFG2LLVM.h - Header file for "VISC Dataflow Graph to Target" ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Pass.h"
+#include "llvm/BuildDFG/BuildDFG.h"
+#include "llvm/SupportVISC/VISCTimer.h"
+
+using namespace llvm;
+using namespace builddfg;
+
+#define TIMER(X) do { if (VISCTimer) { X; } } while (0)
+
+namespace dfg2llvm {
+// Helper Functions
+static inline ConstantInt* getTimerID(Module&, enum visc_TimerID);
+
+// DFG2LLVM abstract class implementation
+class DFG2LLVM : public ModulePass {
+protected:
+  DFG2LLVM(char ID) : ModulePass(ID) {}
+
+  // Member variables
+
+  // Functions
+
+public:
+  // Pure Virtual Functions
+  virtual bool runOnModule(Module &M) = 0;
+
+  // Functions
+  void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.addRequired<BuildDFG>();
+    AU.addPreserved<BuildDFG>();
+  }
+
+};
+
+// Abstract Visitor for Code generation traversal (tree traversal for now)
+class CodeGenTraversal : public DFNodeVisitor {
+
+protected:
+  //Member variables
+  Module &M;
+  BuildDFG &DFG;
+  bool VISCTimer = false;
+  Twine TargetName = "None";
+  
+  // Map from Old function associated with DFNode to new cloned function with
+  // extra index and dimension arguments. This map also serves to find out if
+  // we already have an index and dim extended function copy or not (i.e.,
+  // "Have we visited this function before?")
+  DenseMap<DFNode*, Value*> OutputMap;
+
+  // VISC Runtime API
+  Module* runtimeModule;
+
+  Constant* llvm_visc_initializeTimerSet;
+  Constant* llvm_visc_switchToTimer;
+  Constant* llvm_visc_printTimerSet;
+  GlobalVariable* TimerSet;
+  GlobalVariable* GraphIDAddr;
+  Instruction* InitCall;
+  Instruction* CleanupCall;
+
+
+  // Functions
+  Value* getStringPointer(const Twine& S, Instruction* InsertBefore, const Twine& Name = "");
+  void addIdxDimArgs(Function* F);
+  Argument* getArgumentAt(Function* F, unsigned offset);
+
+  // Pure Virtual Functions
+  virtual void init() = 0;
+  virtual void initRuntimeAPI() = 0;// { errs () << "*******Oops called from base class*******\n";}
+  virtual void codeGen(DFInternalNode* N) = 0;
+  virtual void codeGen(DFLeafNode* N) = 0;
+
+  // Virtual Functions
+  virtual void initializeTimerSet(Instruction*);
+  virtual void switchToTimer(enum visc_TimerID, Instruction*);
+  virtual void printTimerSet(Instruction*);
+
+  virtual ~CodeGenTraversal() {}
+
+
+public:
+
+  // Constructor
+  CodeGenTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) {}
+
+  virtual void visit(DFInternalNode* N) {
+    // If code has already been generated for this internal node, skip the
+    // children
+    if(N->getGenFunc() != NULL)
+      return;
+
+    DEBUG(errs() << "Start: Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n");
+
+    // Follows a bottom-up approach for code generation.
+    // First generate code for all the child nodes
+    for(DFGraph::children_iterator i = N->getChildGraph()->begin(),
+        e = N->getChildGraph()->end(); i != e; ++i) {
+      DFNode* child = *i;
+      child->applyDFNodeVisitor(*this);
+    }
+    // Generate code for this internal node now. This way all the cloned
+    // functions for children exist.
+    codeGen(N);
+    DEBUG(errs() << "DONE: Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n");
+  }
+
+  virtual void visit(DFLeafNode* N) {
+    DEBUG(errs() << "Start: Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n");
+    codeGen(N);
+    DEBUG(errs() << "DONE: Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n");
+  }
+};
+
+// -------------- CodeGenTraversal Implementation -----------------
+
+// Generate Code for declaring a constant string [L x i8] and return a pointer
+// to the start of it.
+Value* CodeGenTraversal::getStringPointer(const Twine& S, Instruction* IB, const Twine& Name) {
+  errs() << "Module pointer: " << &M << "\n";
+ 
+  Constant* SConstant = ConstantDataArray::getString(M.getContext(), S.str(), true);
+  errs () << "String constant  = " << *SConstant << "\n"; 
+  Value* SGlobal = new GlobalVariable(M, SConstant->getType(), true,
+                                      GlobalValue::InternalLinkage, SConstant, Name);
+  errs () << "String global  = " << *SGlobal << "\n"; 
+  Value* Zero = ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 0);
+  Value* GEPArgs[] = {Zero, Zero};
+  errs () << "Zero = " << *Zero << "\n";
+  errs () << "Module = " << *IB->getParent() << "\n";
+  GetElementPtrInst* SPtr = GetElementPtrInst::Create(SGlobal,
+                            ArrayRef<Value*>(GEPArgs, 2), Name+"Ptr", IB);
+  errs() << "String pointer = " << SPtr << "\n";
+  return SPtr;
+}
+
+// Change the argument list of function F to add index and limit arguments
+void CodeGenTraversal::addIdxDimArgs(Function* F) {
+  // Add Index and Dim arguments
+  std::string names[] = {"idx_x", "idx_y", "idx_z", "dim_x", "dim_y", "dim_z"};
+  for (int i = 0; i < 6; ++i) {
+    new Argument(Type::getInt32Ty(F->getContext()), names[i], F);
+  }
+
+  // Create the argument type list with added argument types
+  std::vector<Type*> ArgTypes;
+  for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+      ai != ae; ++ai) {
+    ArgTypes.push_back(ai->getType());
+  }
+  // Adding new arguments to the function argument list, would not change the
+  // function type. We need to change the type of this function to reflect the
+  // added arguments
+  FunctionType* FTy = FunctionType::get(F->getReturnType(), ArgTypes, F->isVarArg());
+  PointerType* PTy = PointerType::get(FTy, cast<PointerType>(F->getType())->getAddressSpace());
+
+  // Change the function type
+  F->mutateType(PTy);
+}
+
+// Traverse the function F argument list to get argument at offset
+Argument* CodeGenTraversal::getArgumentAt(Function* F, unsigned offset) {
+  DEBUG(errs() << "Finding argument " << offset << ":\n");
+  assert((F->getFunctionType()->getNumParams() > offset && offset >= 0)
+         && "Invalid offset to access arguments!");
+  Argument* arg;
+  Function::arg_iterator i = F->arg_begin(), e = F->arg_end();
+  for(; offset != 0 && i!=e; i++) {
+    offset--;
+  }
+  arg = i;
+  DEBUG(errs() << "\t" << *arg <<"\n");
+  return arg;
+}
+
+// Timer Routines
+// Initialize the timer set
+void CodeGenTraversal::initializeTimerSet(Instruction* InsertBefore) {
+  DEBUG(errs() << "Inserting call to: " << *llvm_visc_initializeTimerSet << "\n");
+  TIMER(TimerSet = new GlobalVariable(M,
+                                      Type::getInt8PtrTy(M.getContext()),
+                                      false,
+                                      GlobalValue::CommonLinkage,
+                                      Constant::getNullValue(Type::getInt8PtrTy(M.getContext())),
+                                      "viscTimerSet_"+TargetName);
+
+    Value* TimerSetAddr = CallInst::Create(llvm_visc_initializeTimerSet,
+                                          None,
+                                          "",
+                                          InsertBefore);
+    new StoreInst(TimerSetAddr, TimerSet, InsertBefore);
+  );
+}
+
+void CodeGenTraversal::switchToTimer(enum visc_TimerID timer, Instruction* InsertBefore) {
+  Value* switchArgs[] = {TimerSet, getTimerID(M, timer)};
+  TIMER(CallInst::Create(llvm_visc_switchToTimer,
+                         ArrayRef<Value*>(switchArgs, 2),
+                         "",
+                         InsertBefore));
+}
+
+void CodeGenTraversal::printTimerSet(Instruction* InsertBefore) {
+  Value* TimerName;
+  TIMER(TimerName = getStringPointer(TargetName+"_Timer", InsertBefore));
+  Value* printArgs[] = {TimerSet, TimerName};
+  TIMER(CallInst::Create(llvm_visc_printTimerSet,
+                         ArrayRef<Value*>(printArgs, 2),
+                         "",
+                         InsertBefore));
+}
+
+// Implementation of Helper Functions
+static inline ConstantInt* getTimerID(Module& M, enum visc_TimerID timer) {
+  return ConstantInt::get(Type::getInt32Ty(M.getContext()), timer);
+}
+
+} // End of namespace
+
diff --git a/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp b/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
index ce52a029a4..ecaf0a4139 100644
--- a/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
+++ b/llvm/lib/Transforms/DFG2LLVM_NVPTX/DFG2LLVM_NVPTX.cpp
@@ -21,26 +21,29 @@
 #include "llvm/Transforms/Utils/ValueMapper.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/BuildDFG/BuildDFG.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/Linker.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/SupportVISC/VISCTimer.h"
+#include "llvm/SupportVISC/DFG2LLVM.h"
 
 #include <sstream>
 
 using namespace llvm;
 using namespace builddfg;
+using namespace dfg2llvm;
 
 //STATISTIC(IntrinsicCounter, "Counts number of visc intrinsics greeted");
 
-#define TIMER(X) do { if (VISCTimer) { X; } } while (0)
+#define DECLARE(X) X = M.getOrInsertFunction(#X, \
+    runtimeModule->getFunction(#X)->getFunctionType()); \
+    DEBUG(errs() << *X)
 
 // VISC Command line option to use timer or not
 static cl::opt<bool>
-VISCTimer("visc-timers-ptx", cl::desc("Enable visc timers"));
+VISCTimer_NVPTX("visc-timers-ptx", cl::desc("Enable visc timers"));
 
 namespace {
 // Helper class declarations
@@ -120,51 +123,30 @@ static std::string getPTXFilename(const Module&);
 static std::string getFilenameFromModule(const Module& M);
 static void changeDataLayout(Module &);
 static void changeTargetTriple(Module &);
-static std::string printType(Type*);
-static std::string convertInt(int);
 static void findReturnInst(Function *, std::vector<ReturnInst *> &);
-static inline ConstantInt* getTimerID(Module&, enum visc_TimerID);
 
 
 // DFG2LLVM_NVPTX - The first implementation.
-struct DFG2LLVM_NVPTX : public ModulePass {
+struct DFG2LLVM_NVPTX : public DFG2LLVM {
   static char ID; // Pass identification, replacement for typeid
-  DFG2LLVM_NVPTX() : ModulePass(ID) {}
+  DFG2LLVM_NVPTX() : DFG2LLVM(ID) {}
 
 private:
-  // Member variables
-
-  // Functions
 
 public:
   bool runOnModule(Module &M);
-
-  void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.addRequired<BuildDFG>();
-    AU.addPreserved<BuildDFG>();
-  }
-
-
 };
 
 // Visitor for Code generation traversal (tree traversal for now)
-class CodeGenTraversal : public DFNodeVisitor {
+class CGT_NVPTX : public CodeGenTraversal {
 
 private:
   //Member variables
-  Module &M;
-  BuildDFG &DFG;
   Module &KernelM;
   DFNode* KernelLaunchNode;
   Kernel* kernel;
-  // Map from Old function associated with DFNode to new cloned function with
-  // extra index and dimension arguments. This map also serves to find out if
-  // we already have an index and dim extended function copy or not (i.e.,
-  // "Have we visited this function before?")
-  DenseMap<DFNode*, Value*> OutputMap;
 
   // VISC Runtime API
-  Module* runtimeModule;
   Constant* llvm_visc_ptx_launch;
   Constant* llvm_visc_ptx_wait;
   Constant* llvm_visc_ptx_initContext;
@@ -175,44 +157,31 @@ private:
   Constant* llvm_visc_ptx_getOutput;
   Constant* llvm_visc_ptx_executeNode;
 
-  Constant* llvm_visc_initializeTimerSet;
-  Constant* llvm_visc_switchToTimer;
-  Constant* llvm_visc_printTimerSet;
-  GlobalVariable* TimerSet;
-  GlobalVariable* GraphIDAddr;
-  Instruction* InitCall;
-  Instruction* CleanupCall;
-
-
   //Functions
   std::string getKernelsModuleName(Module &M);
   void fixValueAddrspace(Value* V, unsigned addrspace);
-  Value* getStringPointer(const Twine& S, Instruction* InsertBefore, const Twine& Name = "");
   void changeArgAddrspace(Function* F, unsigned i);
   void addCLMetadata(Function* F);
   void transformFunctionToVoid(Function* F);
-  void initRuntimeAPI();
-  void addIdxDimArgs(Function* F);
-  Argument* getArgumentAt(Function* F, unsigned offset);
-  Value* getInValueAt(DFNode* Child, unsigned i, Function* ParentF_X86,
-                      Instruction* InsertBefore);
   void insertRuntimeCalls(DFInternalNode* N, Kernel* K, const Twine& FileName);
-  void initializeTimerSet(Instruction*);
-  void switchToTimer(enum visc_TimerID, Instruction*);
-  void printTimerSet(Instruction*);
 
+  // Virtual Functions
+  void init() {
+    VISCTimer = VISCTimer_NVPTX;
+    TargetName = "NVPTX";
+  }
+  void initRuntimeAPI();
   void codeGen(DFInternalNode* N);
   void codeGen(DFLeafNode* N);
 
 public:
 
   // Constructor
-  CodeGenTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG), KernelM(*CloneModule(&_M)) {
-    // Initialize Runtime API
+  CGT_NVPTX(Module &_M, BuildDFG &_DFG) : CodeGenTraversal(_M, _DFG), KernelM(*CloneModule(&_M)) {
+    init();
     initRuntimeAPI();
 
     // Copying instead of creating new, in order to preserve required info (metadata)
-
     // Remove functions, global variables and aliases
     std::vector<GlobalVariable*> gvv = std::vector<GlobalVariable*>();
     for (Module::global_iterator mi = KernelM.global_begin(),
@@ -254,30 +223,11 @@ public:
 
   }
 
-  virtual void visit(DFInternalNode* N) {
-    for(DFGraph::children_iterator i = N->getChildGraph()->begin(),
-        e = N->getChildGraph()->end(); i != e; ++i) {
-      DFNode* child = *i;
-      child->applyDFNodeVisitor(*this);
-    }
-
-    DEBUG(errs() << "Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n");
-    codeGen(N);
-    DEBUG(errs() << "DONE" << "\n");
-
-  }
-
-  virtual void visit(DFLeafNode* N) {
-    DEBUG(errs() << "Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n");
-    codeGen(N);
-    DEBUG(errs() << "DONE" << "\n");
-  }
-
   void writeKernelsModule();
 };
 
 // Initialize the VISC runtime API. This makes it easier to insert these calls
-void CodeGenTraversal::initRuntimeAPI() {
+void CGT_NVPTX::initRuntimeAPI() {
 
   // Load Runtime API Module
   SMDiagnostic Err;
@@ -295,53 +245,18 @@ void CodeGenTraversal::initRuntimeAPI() {
     DEBUG(errs() << "Successfully loaded visc-rt API module\n");
 
   // Get or insert the global declarations for launch/wait functions
-  llvm_visc_ptx_launch = M.getOrInsertFunction("llvm_visc_ptx_launch",
-                         runtimeModule->getFunction("llvm_visc_ptx_launch")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_launch);
-
-  llvm_visc_ptx_wait = M.getOrInsertFunction("llvm_visc_ptx_wait",
-                       runtimeModule->getFunction("llvm_visc_ptx_wait")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_wait);
-
-  llvm_visc_ptx_initContext = M.getOrInsertFunction("llvm_visc_ptx_initContext"  ,
-                              runtimeModule->getFunction("llvm_visc_ptx_initContext")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_initContext);
-
-  llvm_visc_ptx_clearContext = M.getOrInsertFunction("llvm_visc_ptx_clearContext"  ,
-                               runtimeModule->getFunction("llvm_visc_ptx_clearContext")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_clearContext);
-
-  llvm_visc_ptx_argument_scalar = M.getOrInsertFunction("llvm_visc_ptx_argument_scalar",
-                                  runtimeModule->getFunction("llvm_visc_ptx_argument_scalar")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_argument_scalar);
-
-  llvm_visc_ptx_argument_ptr = M.getOrInsertFunction("llvm_visc_ptx_argument_ptr",
-                               runtimeModule->getFunction("llvm_visc_ptx_argument_ptr")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_argument_ptr);
-
-  llvm_visc_ptx_free = M.getOrInsertFunction("llvm_visc_ptx_free",
-                       runtimeModule->getFunction("llvm_visc_ptx_free")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_argument_ptr);
-
-  llvm_visc_ptx_getOutput = M.getOrInsertFunction("llvm_visc_ptx_getOutput",
-                            runtimeModule->getFunction("llvm_visc_ptx_getOutput")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_getOutput);
-
-  llvm_visc_ptx_executeNode = M.getOrInsertFunction("llvm_visc_ptx_executeNode",
-                              runtimeModule->getFunction("llvm_visc_ptx_executeNode")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_ptx_executeNode);
-
-  llvm_visc_initializeTimerSet = M.getOrInsertFunction("llvm_visc_initializeTimerSet",
-                                 runtimeModule->getFunction("llvm_visc_initializeTimerSet")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_initializeTimerSet);
-
-  llvm_visc_switchToTimer = M.getOrInsertFunction("llvm_visc_switchToTimer",
-                            runtimeModule->getFunction("llvm_visc_switchToTimer")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_switchToTimer);
-
-  llvm_visc_printTimerSet = M.getOrInsertFunction("llvm_visc_printTimerSet",
-                            runtimeModule->getFunction("llvm_visc_printTimerSet")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_printTimerSet);
+  DECLARE(llvm_visc_ptx_launch);
+  DECLARE(llvm_visc_ptx_wait);
+  DECLARE(llvm_visc_ptx_initContext);
+  DECLARE(llvm_visc_ptx_clearContext);
+  DECLARE(llvm_visc_ptx_argument_scalar);
+  DECLARE(llvm_visc_ptx_argument_ptr);
+  DECLARE(llvm_visc_ptx_free);
+  DECLARE(llvm_visc_ptx_getOutput);
+  DECLARE(llvm_visc_ptx_executeNode);
+  DECLARE(llvm_visc_initializeTimerSet);
+  DECLARE(llvm_visc_switchToTimer);
+  DECLARE(llvm_visc_printTimerSet);
 
   // Insert init context in main
   DEBUG(errs() << "Gen Code to initialize NVPTX Timer\n");
@@ -365,102 +280,13 @@ void CodeGenTraversal::initRuntimeAPI() {
 
 
 }
-void CodeGenTraversal::addIdxDimArgs(Function* F) {
-  // Add Index and Dim arguments
-  std::string names[] = {"idx_x", "idx_y", "idx_z", "dim_x", "dim_y", "dim_z"};
-  for (int i = 0; i < 6; ++i) {
-    new Argument(Type::getInt32Ty(F->getContext()), names[i], F);
-  }
-
-  // Create the argument type list with added argument types
-  std::vector<Type*> ArgTypes;
-  for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
-      ai != ae; ++ai) {
-    ArgTypes.push_back(ai->getType());
-  }
-  // Adding new arguments to the function argument list, would not change the
-  // function type. We need to change the type of this function to reflect the
-  // added arguments
-  FunctionType* FTy = FunctionType::get(F->getReturnType(), ArgTypes, F->isVarArg());
-  PointerType* PTy = PointerType::get(FTy, cast<PointerType>(F->getType())->getAddressSpace());
-
-  // Change the function type
-  F->mutateType(PTy);
-}
-
-/* Traverse the function F argument list to get argument at offset*/
-Argument* CodeGenTraversal::getArgumentAt(Function* F, unsigned offset) {
-  DEBUG(errs() << "Finding argument " << offset << ":\n");
-  assert((F->getFunctionType()->getNumParams() > offset && offset >= 0)
-         && "Invalid offset to access arguments!");
-  Argument* arg;
-  Function::arg_iterator i = F->arg_begin(), e = F->arg_end();
-  for(; offset != 0 && i!=e; i++) {
-    offset--;
-  }
-  arg = i;
-  DEBUG(errs() << "\t" << *arg <<"\n");
-  return arg;
-}
-
-
-Value* CodeGenTraversal::getInValueAt(DFNode* Child, unsigned i, Function* ParentF_X86,
-                                      Instruction* InsertBefore) {
-  // TODO: Assumption is that each input port of a node has just one
-  // incoming edge. May change later on.
-
-  // Find the incoming edge at the requested input port
-  DFEdge* E = Child->getInDFEdgeAt(i);
-  assert(E && "No incoming edge or binding for input element!");
-  // Find the Source DFNode associated with the incoming edge
-  DFNode* SrcDF = E->getSourceDF();
-
-  // If Source DFNode is a dummyNode, edge is from parent. Get the
-  // argument from argument list of this internal node
-  Value* inputVal;
-  if(SrcDF->isEntryNode()) {
-    inputVal = getArgumentAt(ParentF_X86, E->getSourcePosition());
-    DEBUG(errs() << "Argument "<< i<< " = "  << *inputVal << "\n");
-  }
-  else {
-    // edge is from a sibling
-    // Check - code should already be generated for this source dfnode
-    assert(OutputMap.count(SrcDF)
-           && "Source node call not found. Dependency violation!");
-
-    // Find CallInst associated with the Source DFNode using OutputMap
-    Value* CI = OutputMap[SrcDF];
-
-    // Extract element at source position from this call instruction
-    std::vector<unsigned> IndexList;
-    IndexList.push_back(E->getSourcePosition());
-    DEBUG(errs() << "Going to generate ExtarctVal inst from "<< *CI <<"\n");
-    ExtractValueInst* EI = ExtractValueInst::Create(CI, IndexList,
-                           "", InsertBefore);
-    inputVal = EI;
-  }
-  return inputVal;
-}
-
-// Generate Code for declaring a constant string [L x i8] and return a pointer
-// to the start of it.
-Value* CodeGenTraversal::getStringPointer(const Twine& S, Instruction* IB, const Twine& Name) {
-  Constant* SConstant = ConstantDataArray::getString(M.getContext(), S.str(), true);
-  Value* SGlobal = new GlobalVariable(M, SConstant->getType(), true,
-                                      GlobalValue::InternalLinkage, SConstant, Name);
-  Value* Zero = ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 0);
-  Value* GEPArgs[] = {Zero, Zero};
-  GetElementPtrInst* SPtr = GetElementPtrInst::Create(SGlobal,
-                            ArrayRef<Value*>(GEPArgs, 2), Name+"Ptr", IB);
-  return SPtr;
-}
 
 // Generate Code to call the kernel
 // The plan is to replace the internal node with a leaf node. This method is
 // used to generate a function to associate with this leaf node. The function
 // is responsible for all the memory allocation/transfer and invoking the
 // kernel call on the device
-void CodeGenTraversal::insertRuntimeCalls(DFInternalNode* N, Kernel* K, const Twine& FileName) {
+void CGT_NVPTX::insertRuntimeCalls(DFInternalNode* N, Kernel* K, const Twine& FileName) {
   // Check if clone already exists. If it does, it means we have visited this
   // function before.
   assert(N->getGenFunc() == NULL && "Code already generated for this node");
@@ -819,7 +645,7 @@ void CodeGenTraversal::insertRuntimeCalls(DFInternalNode* N, Kernel* K, const Tw
 
 // Right now, only targeting the one level case. In general, device functions
 // can return values so we don't need to change them
-void CodeGenTraversal::codeGen(DFInternalNode* N) {
+void CGT_NVPTX::codeGen(DFInternalNode* N) {
 
   if (!KernelLaunchNode) {
     DEBUG(errs() << "No code generated (host code for kernel launch complete).\n");
@@ -892,46 +718,8 @@ void CodeGenTraversal::codeGen(DFInternalNode* N) {
   }
 
 }
-void CodeGenTraversal::initializeTimerSet(Instruction* InsertBefore) {
-  Value* TimerSetAddr;
-  StoreInst* SI;
-  TIMER(TimerSet = new GlobalVariable(M,
-                                      Type::getInt8PtrTy(M.getContext()),
-                                      false,
-                                      GlobalValue::CommonLinkage,
-                                      Constant::getNullValue(Type::getInt8PtrTy(M.getContext())),
-                                      "viscTimerSet_NVPTX"));
-  DEBUG(errs() << "Inserting GV: " << *TimerSet->getType() << *TimerSet << "\n");
-  DEBUG(errs() << "Inserting call to: " << *llvm_visc_initializeTimerSet << "\n");
-
-  TIMER(TimerSetAddr = CallInst::Create(llvm_visc_initializeTimerSet,
-                                        None,
-                                        "",
-                                        InsertBefore));
-  DEBUG(errs() << "TimerSetAddress = " << *TimerSetAddr << "\n");
-  TIMER(SI = new StoreInst(TimerSetAddr, TimerSet, InsertBefore));
-  DEBUG(errs() << "Store Timer Address in Global variable: " << *SI << "\n");
-}
-
-void CodeGenTraversal::switchToTimer(enum visc_TimerID timer, Instruction* InsertBefore) {
-  Value* switchArgs[] = {TimerSet, getTimerID(M, timer)};
-  TIMER(CallInst::Create(llvm_visc_switchToTimer,
-                         ArrayRef<Value*>(switchArgs, 2),
-                         "",
-                         InsertBefore));
-}
-
-void CodeGenTraversal::printTimerSet(Instruction* InsertBefore) {
-  Value* TimerName;
-  TIMER(TimerName = getStringPointer("NVPTX_Timer", InsertBefore));
-  Value* printArgs[] = {TimerSet, TimerName};
-  TIMER(CallInst::Create(llvm_visc_printTimerSet,
-                         ArrayRef<Value*>(printArgs, 2),
-                         "",
-                         InsertBefore));
-}
 
-void CodeGenTraversal::codeGen(DFLeafNode* N) {
+void CGT_NVPTX::codeGen(DFLeafNode* N) {
 
   // Skip code generation if it is a dummy node
   if(N->isDummyNode()) {
@@ -1271,7 +1059,7 @@ bool DFG2LLVM_NVPTX::runOnModule(Module &M) {
   //    BuildDFG::HandleToDFEdge &HandleToDFEdgeMap = DFG.getHandleToDFEdgeMap();
 
   // Visitor for Code Generation Graph Traversal
-  CodeGenTraversal *CGTVisitor = new CodeGenTraversal(M, DFG);
+  CGT_NVPTX *CGTVisitor = new CGT_NVPTX(M, DFG);
 
   // Iterate over all the DFGs and produce code for each one of them
   for (auto rootNode: Roots) {
@@ -1287,7 +1075,7 @@ bool DFG2LLVM_NVPTX::runOnModule(Module &M) {
   return true;
 }
 
-std::string CodeGenTraversal::getKernelsModuleName(Module &M) {
+std::string CGT_NVPTX::getKernelsModuleName(Module &M) {
   /*SmallString<128> currentDir;
   llvm::sys::fs::current_path(currentDir);
   std::string fileName = getFilenameFromModule(M);
@@ -1297,7 +1085,7 @@ std::string CodeGenTraversal::getKernelsModuleName(Module &M) {
   return mid.append(".kernels.ll");
 }
 
-void CodeGenTraversal::fixValueAddrspace(Value* V, unsigned addrspace) {
+void CGT_NVPTX::fixValueAddrspace(Value* V, unsigned addrspace) {
   assert(isa<PointerType>(V->getType())
          && "Value should be of Pointer Type!");
   PointerType* OldTy = cast<PointerType>(V->getType());
@@ -1314,7 +1102,7 @@ void CodeGenTraversal::fixValueAddrspace(Value* V, unsigned addrspace) {
   }
 }
 
-void CodeGenTraversal::changeArgAddrspace(Function* F, unsigned addrspace) {
+void CGT_NVPTX::changeArgAddrspace(Function* F, unsigned addrspace) {
   std::vector<Type*> ArgTypes;
   for(auto& arg: F->getArgumentList()) {
     DEBUG(errs() << arg << "\n");
@@ -1333,69 +1121,17 @@ void CodeGenTraversal::changeArgAddrspace(Function* F, unsigned addrspace) {
 }
 
 /* Add metadata to module KernelM, for OpenCL kernels */
-void CodeGenTraversal::addCLMetadata(Function *F) {
+void CGT_NVPTX::addCLMetadata(Function *F) {
 
   IRBuilder<true> Builder(F->begin());
 
   SmallVector<Value*,8> KernelMD;
   KernelMD.push_back(F);
+  
+  // TODO: There is additional metadata used by kernel files but we skip them as
+  // they are not mandatory. In future they might be useful to enable
+  // optimizations
 
-  //TODO: For now, we don not add any additional metadata
-  /*
-      // MDNode for the kernel argument address space qualifiers.
-      SmallVector<llvm::Value*, 8> addressQuals;
-      addressQuals.push_back(MDString::get(KernelM.getContext(), "kernel_arg_addr_space"));
-
-      // We don't support images
-      // MDNode for the kernel argument access qualifiers (images only).
-  //    SmallVector<llvm::Value*, 8> accessQuals;
-  //    accessQuals.push_back(MDString::get(KernelM.getContext(), "kernel_arg_access_qual"));
-
-      // MDNode for the kernel argument type names.
-      SmallVector<llvm::Value*, 8> argTypeNames;
-      argTypeNames.push_back(MDString::get(KernelM.getContext(), "kernel_arg_type"));
-
-      //TODO: MDNode for the kernel argument type qualifiers.
-  //    SmallVector<llvm::Value*, 8> argTypeQuals;
-  //    argTypeQuals.push_back(MDString::get(KernelM.getContext(), "kernel_arg_type_qual"));
-
-      // MDNode for the kernel argument names.
-      SmallVector<llvm::Value*, 8> argNames;
-      argNames.push_back(MDString::get(KernelM.getContext(), "kernel_arg_name"));
-
-      for (Function::arg_iterator ai = F->arg_begin(),
-                                    ae = F->arg_end(); ai != ae; ++ai) {
-        Argument *arg = &*ai;
-        Type *argTy = arg->getType();
-
-        if (argTy->isPointerTy()) {
-          Type *pointeeTy = argTy->getPointerElementType();
-          std::string typeName = printType(pointeeTy) + "*";
-          // Get argument type name.
-          argTypeNames.push_back(MDString::get(KernelM.getContext(), typeName));
-
-          // Get address qualifier.
-          addressQuals.push_back(Builder.getInt32(argTy->getPointerAddressSpace()));
-        } else {
-          std::string typeName = printType(argTy);
-          // Get argument type name.
-          argTypeNames.push_back(MDString::get(KernelM.getContext(), typeName));
-
-          // Get address qualifier.
-          addressQuals.push_back(Builder.getInt32(GENERIC_ADDRSPACE));
-
-        }
-
-        // Get argument name.
-        argNames.push_back(MDString::get(KernelM.getContext(), arg->getName()));
-      }
-
-      KernelMD.push_back(MDNode::get(KernelM.getContext(), addressQuals));
-  //    KernelMD.push_back(MDNode::get(KernelM.getContext(), accessQuals));
-      KernelMD.push_back(MDNode::get(KernelM.getContext(), argTypeNames));
-  //    KernelMD.push_back(MDNode::get(KernelM.getContext(), argTypeQuals));
-      KernelMD.push_back(MDNode::get(KernelM.getContext(), argNames));
-  */
   MDNode *MDKernelNode = MDNode::get(KernelM.getContext(), KernelMD);
   NamedMDNode *MDN_kernels = KernelM.getOrInsertNamedMetadata("opencl.kernels");
   MDN_kernels->addOperand(MDKernelNode);
@@ -1408,10 +1144,9 @@ void CodeGenTraversal::addCLMetadata(Function *F) {
   NamedMDNode *MDN_annotations = KernelM.getOrInsertNamedMetadata("nvvm.annotations");
   MDN_annotations->addOperand(MDNvvmAnnotationsNode);
 
-  //!1 = metadata !{void (float addrspace(1)*, float addrspace(1)*, float addrspace(1)*, i32, i32)* @matrixMul, metadata !"kernel", i32 1}
 }
 
-void CodeGenTraversal::writeKernelsModule() {
+void CGT_NVPTX::writeKernelsModule() {
 
   char* ErrorMessage = NULL;
   LLVMModuleRef KernelMRef = wrap(&KernelM);
@@ -1426,7 +1161,7 @@ void CodeGenTraversal::writeKernelsModule() {
   LLVMDisposeModule(KernelMRef);
 }
 
-void CodeGenTraversal::transformFunctionToVoid(Function* F) {
+void CGT_NVPTX::transformFunctionToVoid(Function* F) {
 
   // FIXME: Maybe do that using the Node?
   StructType* FRetTy = cast<StructType>(F->getReturnType());
@@ -1653,21 +1388,6 @@ static void changeTargetTriple(Module &M) {
   return;
 }
 
-// Helper function, generate a string representation of a type
-static std::string printType(Type* ty) {
-  std::string type_str;
-  raw_string_ostream rso(type_str);
-  ty->print(rso);
-  return rso.str();
-}
-
-// Helper function, convert int to string
-static std::string convertInt(int number) {
-  std::stringstream ss;//create a stringstream
-  ss << number;//add number to the stream
-  return ss.str();//return a string with the contents of the stream
-}
-
 // Helper function, populate a vector with all return statements in a function
 static void findReturnInst(Function* F, std::vector<ReturnInst *> & ReturnInstVec) {
   for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
@@ -1679,10 +1399,6 @@ static void findReturnInst(Function* F, std::vector<ReturnInst *> & ReturnInstVe
   }
 }
 
-static inline ConstantInt* getTimerID(Module& M, enum visc_TimerID timer) {
-  return ConstantInt::get(Type::getInt32Ty(M.getContext()), timer);
-}
-
 } // End of namespace
 
 char DFG2LLVM_NVPTX::ID = 0;
diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
index e0aa75e988..1419b4446e 100644
--- a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
+++ b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
@@ -14,33 +14,32 @@
 #include "llvm/Transforms/Utils/ValueMapper.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/BuildDFG/BuildDFG.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/Linker.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Constant.h"
-#include "llvm/SupportVISC/VISCTimer.h"
+#include "llvm/SupportVISC/DFG2LLVM.h"
 
 using namespace llvm;
 using namespace builddfg;
+using namespace dfg2llvm;
 
 //STATISTIC(IntrinsicCounter, "Counts number of visc intrinsics greeted");
-#define TIMER(X) do { if (VISCTimer) { X; } } while (0)
+#define DECLARE(X) X = M.getOrInsertFunction(#X, \
+    runtimeModule->getFunction(#X)->getFunctionType()); \
+    DEBUG(errs() << *X)
 
 // VISC Command line option to use timer or not
 static cl::opt<bool>
-VISCTimer("visc-timers-x86", cl::desc("Enable visc timers"));
+VISCTimer_X86("visc-timers-x86", cl::desc("Enable visc timers"));
 
 namespace {
 
-// Helper Function
-static inline ConstantInt* getTimerID(Module&, enum visc_TimerID);
-
 // DFG2LLVM_X86 - The first implementation.
-struct DFG2LLVM_X86 : public ModulePass {
+struct DFG2LLVM_X86 : public DFG2LLVM {
   static char ID; // Pass identification, replacement for typeid
-  DFG2LLVM_X86() : ModulePass(ID) {}
+  DFG2LLVM_X86() :DFG2LLVM(ID) {}
 
 private:
   // Member variables
@@ -49,28 +48,15 @@ private:
 
 public:
   bool runOnModule(Module &M);
-
-  void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.addRequired<BuildDFG>();
-    AU.addPreserved<BuildDFG>();
-  }
-
-
 };
 
 // Visitor for Code generation traversal (tree traversal for now)
-class CodeGenTraversal : public DFNodeVisitor {
+class CGT_X86 : public CodeGenTraversal {
 
 private:
   //Member variables
-  Module &M;
-  BuildDFG &DFG;
-
-  // Map from Node to Instruction containing output of a node
-  DenseMap<DFNode*, Value*> OutputMap;
 
   // VISC Runtime API
-  Module* runtimeModule;
   Constant* llvm_visc_x86_launch;
   Constant* llvm_visc_x86_wait;
   Constant* llvm_visc_x86_push;
@@ -78,68 +64,34 @@ private:
   Constant* llvm_visc_x86_getDimLimit;
   Constant* llvm_visc_x86_getDimInstance;
 
-  Constant* llvm_visc_initializeTimerSet;
-  Constant* llvm_visc_switchToTimer;
-  Constant* llvm_visc_printTimerSet;
-
-  GlobalVariable* TimerSet;
-
-  //Functionis
-  Value* getStringPointer(const Twine& S, Instruction* InsertBefore, const Twine& Name = "");
-  void initRuntimeAPI();
+  //Functions
   std::vector<IntrinsicInst*>* getWaitList(Value* LI);
-  void addIdxDimArgs(Function* F);
   Value* addLoop(Instruction* I, Value* limit, const Twine& indexName = "");
   Argument* getArgumentFromEnd(Function* F, unsigned offset);
-  Argument* getArgumentAt(Function* F, unsigned offset);
   Value* getInValueAt(DFNode* Child, unsigned i, Function* ParentF_X86,
                       Instruction* InsertBefore);
   void invokeChild_X86(DFNode* C, Function* F_X86, ValueToValueMapTy &VMap,
                        Instruction* InsertBefore);
   void invokeChild_PTX(DFNode* C, Function* F_X86, ValueToValueMapTy &VMap,
                        Instruction* InsertBefore);
+
+  // Virtual Functions
+  void init() {
+    VISCTimer = VISCTimer_X86;
+    TargetName = "X86";
+  }
+  void initRuntimeAPI();
   void codeGen(DFInternalNode* N);
   void codeGen(DFLeafNode* N);
-  void initializeTimerSet(Instruction*);
-  void switchToTimer(enum visc_TimerID, Instruction*);
-  void printTimerSet(Instruction*);
 
 public:
   // Constructor
-  CodeGenTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) {
+  CGT_X86(Module &_M, BuildDFG &_DFG) : CodeGenTraversal(_M, _DFG) {
+    init();
     initRuntimeAPI();
   }
 
   void codeGenLaunch(DFInternalNode* Root);
-
-  virtual void visit(DFInternalNode* N) {
-    // If code has already been generated for this internal node, skip the
-    // children
-    if(N->getGenFunc() != NULL)
-      return;
-
-    DEBUG(errs() << "Start: Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n");
-
-    // Follows a bottom-up approach for code generation.
-    // First generate code for all the child nodes
-    for(DFGraph::children_iterator i = N->getChildGraph()->begin(),
-        e = N->getChildGraph()->end(); i != e; ++i) {
-      DFNode* child = *i;
-      child->applyDFNodeVisitor(*this);
-    }
-    // Generate code for this internal node now. This way all the cloned
-    // functions for children exist.
-    codeGen(N);
-    DEBUG(errs() << "DONE: Generating Code for Node (I) - " << N->getFuncPointer()->getName() << "\n");
-  }
-
-  virtual void visit(DFLeafNode* N) {
-    DEBUG(errs() << "Start: Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n");
-    codeGen(N);
-    DEBUG(errs() << "DONE: Generating Code for Node (L) - " << N->getFuncPointer()->getName() << "\n");
-  }
-
-
 };
 
 bool DFG2LLVM_X86::runOnModule(Module &M) {
@@ -155,7 +107,7 @@ bool DFG2LLVM_X86::runOnModule(Module &M) {
   // BuildDFG::HandleToDFEdge &HandleToDFEdgeMap = DFG.getHandleToDFEdgeMap();
 
   // Visitor for Code Generation Graph Traversal
-  CodeGenTraversal *CGTVisitor = new CodeGenTraversal(M, DFG);
+  CGT_X86 *CGTVisitor = new CGT_X86(M, DFG);
 
   // Iterate over all the DFGs and produce code for each one of them
   for (auto rootNode: Roots) {
@@ -173,7 +125,7 @@ bool DFG2LLVM_X86::runOnModule(Module &M) {
 }
 
 // Initialize the VISC runtime API. This makes it easier to insert these calls
-void CodeGenTraversal::initRuntimeAPI() {
+void CGT_X86::initRuntimeAPI() {
 
   // Load Runtime API Module
   SMDiagnostic Err;
@@ -192,41 +144,15 @@ void CodeGenTraversal::initRuntimeAPI() {
     DEBUG(errs() << "Successfully loaded visc-rt API module\n");
 
   // Get or insert the global declarations for launch/wait functions
-  llvm_visc_x86_launch = M.getOrInsertFunction("llvm_visc_x86_launch",
-                         runtimeModule->getFunction("llvm_visc_x86_launch")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_x86_launch);
-
-  llvm_visc_x86_wait = M.getOrInsertFunction("llvm_visc_x86_wait",
-                       runtimeModule->getFunction("llvm_visc_x86_wait")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_x86_wait);
-
-  llvm_visc_x86_push = M.getOrInsertFunction("llvm_visc_x86_push",
-                       runtimeModule->getFunction("llvm_visc_x86_push")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_x86_push);
-
-  llvm_visc_x86_pop = M.getOrInsertFunction("llvm_visc_x86_pop",
-                       runtimeModule->getFunction("llvm_visc_x86_pop")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_x86_pop);
-
-  llvm_visc_x86_getDimLimit = M.getOrInsertFunction("llvm_visc_x86_getDimLimit",
-                       runtimeModule->getFunction("llvm_visc_x86_getDimLimit")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_x86_getDimLimit);
-
-  llvm_visc_x86_getDimInstance = M.getOrInsertFunction("llvm_visc_x86_getDimInstance",
-                       runtimeModule->getFunction("llvm_visc_x86_getDimInstance")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_x86_getDimInstance);
-
-  llvm_visc_initializeTimerSet = M.getOrInsertFunction("llvm_visc_initializeTimerSet",
-                                 runtimeModule->getFunction("llvm_visc_initializeTimerSet")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_initializeTimerSet);
-
-  llvm_visc_switchToTimer = M.getOrInsertFunction("llvm_visc_switchToTimer",
-                            runtimeModule->getFunction("llvm_visc_switchToTimer")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_switchToTimer);
-
-  llvm_visc_printTimerSet = M.getOrInsertFunction("llvm_visc_printTimerSet",
-                            runtimeModule->getFunction("llvm_visc_printTimerSet")->getFunctionType());
-  DEBUG(errs() << *llvm_visc_printTimerSet);
+  DECLARE(llvm_visc_x86_launch);
+  DECLARE(llvm_visc_x86_wait);
+  DECLARE(llvm_visc_x86_push);
+  DECLARE(llvm_visc_x86_pop);
+  DECLARE(llvm_visc_x86_getDimLimit);
+  DECLARE(llvm_visc_x86_getDimInstance);
+  DECLARE(llvm_visc_initializeTimerSet);
+  DECLARE(llvm_visc_switchToTimer);
+  DECLARE(llvm_visc_printTimerSet);
 
   // Insert init context in main
   Function* VI = M.getFunction("llvm.visc.init");
@@ -248,7 +174,7 @@ void CodeGenTraversal::initRuntimeAPI() {
 
 /* Returns vector of all wait instructions
  */
-std::vector<IntrinsicInst*>* CodeGenTraversal::getWaitList(Value* GraphID) {
+std::vector<IntrinsicInst*>* CGT_X86::getWaitList(Value* GraphID) {
   std::vector<IntrinsicInst*>* WaitList = new std::vector<IntrinsicInst*>();
   // It must have been loaded from memory somewhere
   for(Value::use_iterator ui = GraphID->use_begin(),
@@ -265,33 +191,10 @@ std::vector<IntrinsicInst*>* CodeGenTraversal::getWaitList(Value* GraphID) {
   return WaitList;
 }
 
-void CodeGenTraversal::addIdxDimArgs(Function* F) {
-  // Add Index and Dim arguments
-  std::string names[] = {"idx_x", "idx_y", "idx_z", "dim_x", "dim_y", "dim_z"};
-  for (int i = 0; i < 6; ++i) {
-    new Argument(Type::getInt32Ty(F->getContext()), names[i], F);
-  }
-
-  // Create the argument type list with added argument types
-  std::vector<Type*> ArgTypes;
-  for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
-      ai != ae; ++ai) {
-    ArgTypes.push_back(ai->getType());
-  }
-  // Adding new arguments to the function argument list, would not change the
-  // function type. We need to change the type of this function to reflect the
-  // added arguments
-  FunctionType* FTy = FunctionType::get(F->getReturnType(), ArgTypes, F->isVarArg());
-  PointerType* PTy = PointerType::get(FTy, cast<PointerType>(F->getType())->getAddressSpace());
-
-  // Change the function type
-  F->mutateType(PTy);
-}
-
 /* Traverse the function argument list in reverse order to get argument at a
  * distance offset fromt he end of argument list of function F
  */
-Argument* CodeGenTraversal::getArgumentFromEnd(Function* F, unsigned offset) {
+Argument* CGT_X86::getArgumentFromEnd(Function* F, unsigned offset) {
   assert((F->getFunctionType()->getNumParams() >= offset && offset > 0)
          && "Invalid offset to access arguments!");
   Function::arg_iterator e = F->arg_end();
@@ -305,35 +208,6 @@ Argument* CodeGenTraversal::getArgumentFromEnd(Function* F, unsigned offset) {
   return arg;
 }
 
-// Generate Code for declaring a constant string [L x i8] and return a pointer
-// to the start of it.
-Value* CodeGenTraversal::getStringPointer(const Twine& S, Instruction* IB, const Twine& Name) {
-  Constant* SConstant = ConstantDataArray::getString(M.getContext(), S.str(), true);
-  Value* SGlobal = new GlobalVariable(M, SConstant->getType(), true,
-                                      GlobalValue::InternalLinkage, SConstant, Name);
-  Value* Zero = ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 0);
-  Value* GEPArgs[] = {Zero, Zero};
-  GetElementPtrInst* SPtr = GetElementPtrInst::Create(SGlobal,
-                            ArrayRef<Value*>(GEPArgs, 2), Name+"Ptr", IB);
-  return SPtr;
-}
-
-
-/* Traverse the function F argument list to get argument at offset*/
-Argument* CodeGenTraversal::getArgumentAt(Function* F, unsigned offset) {
-  assert((F->getFunctionType()->getNumParams() > offset && offset >= 0)
-         && "Invalid offset to access arguments!");
-
-  Argument* arg;
-  Function::arg_iterator i = F->arg_begin(), e = F->arg_end();
-  for(; offset != 0 && i!=e; i++) {
-    offset--;
-  }
-  arg = i;
-  DEBUG(errs() << *F);
-  DEBUG(errs() << *arg <<"\n");
-  return arg;
-}
 
 /* Add Loop around the instruction I
  * Algorithm:
@@ -346,7 +220,7 @@ Argument* CodeGenTraversal::getArgumentAt(Function* F, unsigned offset) {
  * which loops over bidy if true and goes to end if false
  * (5) Update phi node of body
  */
-Value* CodeGenTraversal::addLoop(Instruction* I, Value* limit, const Twine& indexName) {
+Value* CGT_X86::addLoop(Instruction* I, Value* limit, const Twine& indexName) {
   BasicBlock* Entry = I->getParent();
   BasicBlock* ForBody = Entry->splitBasicBlock(I, "for.body");
 
@@ -385,7 +259,7 @@ Value* CodeGenTraversal::addLoop(Instruction* I, Value* limit, const Twine& inde
   return IndexPhi;
 }
 
-void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
+void CGT_X86::codeGenLaunch(DFInternalNode* Root) {
   // TODO: Place an assert to check if the constant passed by launch intrinsic
   // as the number of arguments to DFG is same as the number of arguments of the
   // root of DFG
@@ -504,7 +378,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
 
 }
 
-Value* CodeGenTraversal::getInValueAt(DFNode* Child, unsigned i, Function* ParentF_X86, Instruction* InsertBefore) {
+Value* CGT_X86::getInValueAt(DFNode* Child, unsigned i, Function* ParentF_X86, Instruction* InsertBefore) {
   // TODO: Assumption is that each input port of a node has just one
   // incoming edge. May change later on.
 
@@ -541,7 +415,7 @@ Value* CodeGenTraversal::getInValueAt(DFNode* Child, unsigned i, Function* Paren
   return inputVal;
 }
 
-void CodeGenTraversal::invokeChild_X86(DFNode* C, Function* F_X86,
+void CGT_X86::invokeChild_X86(DFNode* C, Function* F_X86,
                                        ValueToValueMapTy &VMap,Instruction* IB) {
   Function* CF = C->getFuncPointer();
 
@@ -618,7 +492,7 @@ void CodeGenTraversal::invokeChild_X86(DFNode* C, Function* F_X86,
   errs() << *CI->getParent()->getParent();
 }
 
-void CodeGenTraversal::codeGen(DFInternalNode* N) {
+void CGT_X86::codeGen(DFInternalNode* N) {
   // Check if clone already exists. If it does, it means we have visited this
   // function before and nothing else needs to be done for this leaf node.
   if(N->getGenFunc() != NULL)
@@ -726,7 +600,7 @@ void CodeGenTraversal::codeGen(DFInternalNode* N) {
 }
 
 // Code generation for leaf nodes
-void CodeGenTraversal::codeGen(DFLeafNode* N) {
+void CGT_X86::codeGen(DFLeafNode* N) {
   // Skip code generation if it is a dummy node
   if(N->isDummyNode()) {
     DEBUG(errs() << "Skipping dummy node\n");
@@ -957,46 +831,6 @@ void CodeGenTraversal::codeGen(DFLeafNode* N) {
   DEBUG(errs() << *F_X86);
 }
 
-void CodeGenTraversal::initializeTimerSet(Instruction* InsertBefore) {
-  DEBUG(errs() << "Inserting call to: " << *llvm_visc_initializeTimerSet << "\n");
-  TIMER(TimerSet = new GlobalVariable(M,
-                                      Type::getInt8PtrTy(M.getContext()),
-                                      false,
-                                      GlobalValue::CommonLinkage,
-                                      Constant::getNullValue(Type::getInt8PtrTy(M.getContext())),
-                                      "viscTimerSet_X86");
-
-    Value* TimerSetAddr = CallInst::Create(llvm_visc_initializeTimerSet,
-                                          None,
-                                          "",
-                                          InsertBefore);
-    StoreInst* SI = new StoreInst(TimerSetAddr, TimerSet, InsertBefore);
-  );
-}
-
-void CodeGenTraversal::switchToTimer(enum visc_TimerID timer, Instruction* InsertBefore) {
-  Value* switchArgs[] = {TimerSet, getTimerID(M, timer)};
-  TIMER(CallInst::Create(llvm_visc_switchToTimer,
-                         ArrayRef<Value*>(switchArgs, 2),
-                         "",
-                         InsertBefore));
-}
-
-void CodeGenTraversal::printTimerSet(Instruction* InsertBefore) {
-  Value* TimerName;
-  TIMER(TimerName = getStringPointer("X86_Timer", InsertBefore));
-  Value* printArgs[] = {TimerSet, TimerName};
-  TIMER(CallInst::Create(llvm_visc_printTimerSet,
-                         ArrayRef<Value*>(printArgs, 2),
-                         "",
-                         InsertBefore));
-}
-
-static inline ConstantInt* getTimerID(Module& M, enum visc_TimerID timer) {
-  return ConstantInt::get(Type::getInt32Ty(M.getContext()), timer);
-}
-
-
 } // End of namespace
 
 char DFG2LLVM_X86::ID = 0;
-- 
GitLab