diff --git a/llvm/include/llvm/SupportVISC/VISCTimer.h b/llvm/include/llvm/SupportVISC/VISCTimer.h
index e1fb2762f31c2b68bfe20cbb54b0e0708319b0e3..9151049914d2e8f7ff541a8024b771ac91846c2d 100644
--- a/llvm/include/llvm/SupportVISC/VISCTimer.h
+++ b/llvm/include/llvm/SupportVISC/VISCTimer.h
@@ -86,6 +86,7 @@ enum visc_TimerID {
   visc_TimerID_OVERLAP,		/* Time double-counted in asynchronous and
 				 * host activity: automatically filled in,
 				 * not intended for direct usage */
+  // GPU FUNCTION
   visc_TimerID_INIT_CTX,
   visc_TimerID_CLEAR_CTX,
   visc_TimerID_COPY_SCALAR,
@@ -96,6 +97,12 @@ enum visc_TimerID {
   visc_TimerID_MEM_TRACK,
   visc_TimerID_MEM_UNTRACK,
   visc_TimerID_MISC,
+  // LAUNCH FUNCTION
+  visc_TimerID_PTHREAD_CREATE,
+  visc_TimerID_ARG_UNPACK,
+  visc_TimerID_COMPUTATION,
+  visc_TimerID_OUTPUT_PACK,
+  visc_TimerID_OUTPUT_UNPACK,
 
   visc_TimerID_LAST		/* Number of timer IDs */
 };
diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
index 88c9a1ee3d0574fed47c7af22acc3a0f982e58b0..bd6aa65aa1379e83988f8fd9a17e1a90fb876de4 100644
--- a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
+++ b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp
@@ -78,6 +78,8 @@ private:
   Constant* llvm_visc_switchToTimer;
   Constant* llvm_visc_printTimerSet;
 
+  GlobalVariable* TimerSet;
+
   //Functions
   void initRuntimeAPI();
   std::vector<IntrinsicInst*>* getWaitList(Value* LI);
@@ -185,6 +187,36 @@ void CodeGenTraversal::initRuntimeAPI() {
                        runtimeModule->getFunction("llvm_visc_x86_wait")->getFunctionType());
   DEBUG(errs() << *llvm_visc_x86_wait);
 
+  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);
+
+  // Insert init timer in main
+  for (Module::iterator mi = M.begin(), me = M.end(); mi != me; ++mi) {
+    Function* f = &*mi;
+    errs() << "Function: " << f->getName() << "\n";
+    if(f->getName().equals("main")) {
+      DEBUG(errs() << "Initializing context" << "\n");
+      for(inst_iterator i = inst_begin(f), e = inst_end(f); i != e; ++i) {
+        //if(Label)
+      }
+      errs() << "First instruction: " << *inst_begin(f) << "\n";
+      Instruction* I = &*inst_begin(f);
+      initializeTimerSet(I);
+      switchToTimer(visc_TimerID_NONE, I);
+    }
+  }
+
+
+
 }
 
 /* Returns vector of all wait instructions
@@ -313,12 +345,13 @@ Value* CodeGenTraversal::addLoop(Instruction* I, Value* limit, const Twine& inde
 }
 
 void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
-  // TODO: Place an assert to check if the constant passed bu launch intrinsic
+  // 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
   DEBUG(errs() << "Generating Launch Function\n");
   // Get Launch Instruction
   IntrinsicInst* LI = Root->getInstruction();
+  switchToTimer(visc_TimerID_PTHREAD_CREATE, LI);
   DEBUG(errs() << "Generating Launch Function\n");
 
   /* Now we have all the necessary global declarations necessary to generate the
@@ -351,6 +384,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
   ReturnInst* RI = ReturnInst::Create(AppFunc->getContext(),
                                       Constant::getNullValue(AppFunc->getReturnType()),
                                       BB);
+  switchToTimer(visc_TimerID_ARG_UNPACK, RI);
 
   DEBUG(errs() << "Created Empty Launch Function\n");
   // Find the X86 function generated for Root and
@@ -391,6 +425,9 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
     argNum++;
     data = GEP;
   }
+  // Add timers around Call to RootF_X86 function
+  switchToTimer(visc_TimerID_COMPUTATION, CI);
+  switchToTimer(visc_TimerID_OUTPUT_PACK, RI);
 
   // Code for returning the output
   CastInst* OutputAddrCast = CastInst::CreatePointerCast(data,
@@ -398,6 +435,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
                              CI->getName()+".addr",
                              RI);
   new StoreInst(CI, OutputAddrCast, RI);
+  switchToTimer(visc_TimerID_NONE, RI);
 
   DEBUG(errs() << "Application specific function:\n");
   DEBUG(errs() << *AppFunc << "\n");
@@ -420,6 +458,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) {
                                            ArrayRef<Value*>(LaunchInst),
                                            "");
     ReplaceInstWithInst(waitI, waitI_X86);
+    printTimerSet(waitI_X86->getNextNode());
     DEBUG(errs() << *waitI_X86 << "\n");
   }
 
@@ -832,22 +871,37 @@ void CodeGenTraversal::codeGen(DFLeafNode* N) {
 }
 
 void CodeGenTraversal::initializeTimerSet(Instruction* InsertBefore) {
-  TIMER(CallInst::Create(llvm_visc_initializeTimerSet,
-                         None,
-                         "",
-                         InsertBefore));
+  Value* TimerSetAddr;
+  StoreInst* SI;
+  TIMER(TimerSet = new GlobalVariable(M,
+                                      Type::getInt8PtrTy(M.getContext()),
+                                      false,
+                                      GlobalValue::CommonLinkage,
+                                      Constant::getNullValue(Type::getInt8PtrTy(M.getContext())),
+                                      "viscTimerSet_X86"));
+  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*>(getTimerID(M, timer)),
+                         ArrayRef<Value*>(switchArgs, 2),
                          "",
                          InsertBefore));
 }
 
 void CodeGenTraversal::printTimerSet(Instruction* InsertBefore) {
   TIMER(CallInst::Create(llvm_visc_printTimerSet,
-                         None,
+                         ArrayRef<Value*>(TimerSet),
                          "",
                          InsertBefore));
 }
diff --git a/llvm/projects/visc-rt/visc-rt.cpp b/llvm/projects/visc-rt/visc-rt.cpp
index de348979bff4a86891f078a1476cff82f31c522d..27ab2b0238e61fa680be39e99190a189591f4809 100644
--- a/llvm/projects/visc-rt/visc-rt.cpp
+++ b/llvm/projects/visc-rt/visc-rt.cpp
@@ -804,7 +804,8 @@ visc_PrintTimerSet(struct visc_TimerSet *timers)
   const char *categories[] = {
     "IO", "Kernel", "Copy", "Driver", "Copy Async", "Compute", "Overlap",
     "Init_Ctx", "Clear_Ctx", "Copy_Scalar", "Copy_Ptr", "Mem_Free",
-    "Read_Output", "Setup", "Mem_Track", "Mem_Untrack", "Misc"
+    "Read_Output", "Setup", "Mem_Track", "Mem_Untrack", "Misc",
+    "Pthread_Create", "Arg_Unpack", "Computation", "Output_Pack", "Output_Unpack"
 
   };
 
@@ -1184,7 +1185,9 @@ void llvm_visc_switchToTimer(void** timerSet, enum visc_TimerID timer) {
   visc_SwitchToTimer((visc_TimerSet*)(*timerSet), timer);
 }
 void llvm_visc_printTimerSet(void** timerSet) {
+  cout<< "Entered Print timer set\n";
   visc_PrintTimerSet((visc_TimerSet*) (*timerSet));
+  cout<< "Exiting Print timer set\n";
 }
 
 void* llvm_visc_initializeTimerSet() {
diff --git a/llvm/test/VISC/parboil/common/mk/visc.mk b/llvm/test/VISC/parboil/common/mk/visc.mk
index a6c54b943ec32177cddc2609f1dc5b2d84294c9a..68532ef6238ff351ba1e4470eaee47314a633d31 100644
--- a/llvm/test/VISC/parboil/common/mk/visc.mk
+++ b/llvm/test/VISC/parboil/common/mk/visc.mk
@@ -23,7 +23,7 @@ VISC_OPTFLAGS = -load LLVMBuildDFG.so -load LLVMDFG2LLVM_NVPTX.so -load LLVMDFG2
 HOST_LINKFLAGS =
 
 ifeq ($(NO_TIMER),)
-  VISC_OPTFLAGS+=-visc-timers
+  VISC_OPTFLAGS+=-visc-timers-x86 -visc-timers-ptx
 endif