diff --git a/hpvm/include/SupportHPVM/DFG2LLVM.h b/hpvm/include/SupportHPVM/DFG2LLVM.h
index 365fd2ebdde43a0a29494d6c3295cc36a9c9d740..ae3a8cd9063649494bb26f3a463d38b1320cb616 100644
--- a/hpvm/include/SupportHPVM/DFG2LLVM.h
+++ b/hpvm/include/SupportHPVM/DFG2LLVM.h
@@ -174,6 +174,9 @@ bool CodeGenTraversal::checkPreferredTarget(DFNode *N, hpvm::Target T) {
   case hpvm::CPU_TARGET:
     HintNode = M->getOrInsertNamedMetadata("hpvm_hint_cpu");
     break;
+  case hpvm::PROMISE_TARGET:
+    HintNode = M->getOrInsertNamedMetadata("hpvm_hint_promise");
+    break;
   default:
     llvm_unreachable("Target Not supported yet!");
   }
@@ -204,11 +207,13 @@ bool CodeGenTraversal::preferredTargetIncludes(DFNode *N, hpvm::Target T) {
   case hpvm::CPU_TARGET:
     HintNode.push_back(M->getOrInsertNamedMetadata("hpvm_hint_cpu"));
     HintNode.push_back(M->getOrInsertNamedMetadata("hpvm_hint_cpu_gpu"));
-    HintNode.push_back(M->getOrInsertNamedMetadata("hpvm_hint_cpu_spir"));
     break;
   case hpvm::CUDNN_TARGET:
     HintNode.push_back(M->getOrInsertNamedMetadata("hpvm_hint_cudnn"));
     break;
+  case hpvm::PROMISE_TARGET:
+    HintNode.push_back(M->getOrInsertNamedMetadata("hpvm_hint_promise"));
+    break;
   case hpvm::CPU_OR_GPU_TARGET:
     assert(false && "Target should be one of CPU/GPU\n");
     break;
@@ -225,7 +230,6 @@ bool CodeGenTraversal::preferredTargetIncludes(DFNode *N, hpvm::Target T) {
         return true;
     }
   }
-
   return false;
 }
 
diff --git a/hpvm/include/SupportHPVM/DFGraph.h b/hpvm/include/SupportHPVM/DFGraph.h
index d4c6d2d3773f91054653151243848480ba57210f..9e938e301da58b9b2bed5114ca184615dc78c3aa 100644
--- a/hpvm/include/SupportHPVM/DFGraph.h
+++ b/hpvm/include/SupportHPVM/DFGraph.h
@@ -46,12 +46,14 @@ struct TargetGenFunctions {
   Function *CPUGenFunc;
   Function *GPUGenFunc;
   Function *CUDNNGenFunc;
+  Function *PROMISEGenFunc;
 };
 
 struct TargetGenFuncInfo {
   bool cpu_hasCPUFunc;
   bool gpu_hasCPUFunc;
   bool cudnn_hasCPUFunc;
+  bool promise_hasCPUFunc;
 };
 
 class DFGraph {
@@ -355,6 +357,12 @@ public:
     case hpvm::GPU_TARGET:
       GenFuncInfo.gpu_hasCPUFunc = isCPUFunc;
       break;
+    case hpvm::PROMISE_TARGET:
+      GenFuncInfo.promise_hasCPUFunc = isCPUFunc;
+      break;
+    case hpvm::CUDNN_TARGET:
+      GenFuncInfo.cudnn_hasCPUFunc = isCPUFunc;
+      break;
     case hpvm::CPU_OR_GPU_TARGET:
       break;
     default:
@@ -374,6 +382,8 @@ public:
       return GenFuncInfo.gpu_hasCPUFunc;
     case hpvm::CUDNN_TARGET:
       return GenFuncInfo.cudnn_hasCPUFunc;
+    case hpvm::PROMISE_TARGET:
+      return GenFuncInfo.promise_hasCPUFunc;
     case hpvm::CPU_OR_GPU_TARGET:
       assert(false && "Single target expected (CPU/GPU/SPIR/CUDNN/PROMISE)\n");
     default:
@@ -409,6 +419,14 @@ public:
       GenFuncs.CUDNNGenFunc = F;
       GenFuncInfo.cudnn_hasCPUFunc = isCPUFunc;
       break;
+    case hpvm::PROMISE_TARGET:
+      if (GenFuncs.PROMISEGenFunc != NULL) {
+         DEBUG(errs() << "Warning: Second generated PROMISE function for node "
+                 << FuncPointer->getName() << "\n");
+      }
+      GenFuncs.PROMISEGenFunc = F;
+      GenFuncInfo.promise_hasCPUFunc = isCPUFunc;
+      break;
     case hpvm::CPU_OR_GPU_TARGET:
       assert(false && "A node function should be set with a tag specifying its \
                 type, not the node hint itself\n");
@@ -429,6 +447,8 @@ public:
       return GenFuncs.GPUGenFunc;
     case hpvm::CUDNN_TARGET:
       return GenFuncs.CUDNNGenFunc;
+    case hpvm::PROMISE_TARGET:
+      return GenFuncs.PROMISEGenFunc;
     case hpvm::CPU_OR_GPU_TARGET:
       assert(false &&
              "Requesting genarated node function with dual tag instead of \
@@ -455,6 +475,10 @@ public:
       GenFuncs.CUDNNGenFunc = NULL;
       GenFuncInfo.cudnn_hasCPUFunc = false;
       break;
+    case hpvm::PROMISE_TARGET:
+      GenFuncs.PROMISEGenFunc = NULL;
+      GenFuncInfo.promise_hasCPUFunc = false;
+      break;
     case hpvm::CPU_OR_GPU_TARGET:
       assert(false &&
              "Removing genarated node function with dual tag instead of \
@@ -699,10 +723,12 @@ DFNode::DFNode(IntrinsicInst *_II, Function *_FuncPointer, hpvm::Target _Hint,
   GenFuncs.CPUGenFunc = NULL;
   GenFuncs.GPUGenFunc = NULL;
   GenFuncs.CUDNNGenFunc = NULL;
+  GenFuncs.PROMISEGenFunc = NULL;
 
   GenFuncInfo.cpu_hasCPUFunc = false;
   GenFuncInfo.gpu_hasCPUFunc = false;
   GenFuncInfo.cudnn_hasCPUFunc = false;
+  GenFuncInfo.promise_hasCPUFunc = false;
 }
 
 void DFNode::setRank(unsigned r) {
@@ -865,11 +891,11 @@ bool DFNode::hasSideEffects() {
 
 //===--------------------- DFInternalNode Outlined Functions --------------===//
 void DFInternalNode::addEdgeToDFGraph(DFEdge *E) {
-  errs() << "----- ADD EDGE TO DFGRAPH\n";
+  //errs() << "----- ADD EDGE TO DFGRAPH\n";
   DFNode *S = E->getSourceDF();
   DFNode *D = E->getDestDF();
-  errs() << "INIT SOURCE NODE: " << S << "\n";
-  errs() << "INIT DEST NODE: " << D << "\n";
+  //errs() << "INIT SOURCE NODE: " << S << "\n";
+  //errs() << "INIT DEST NODE: " << D << "\n";
 
   assert(std::find(childGraph->begin(), childGraph->end(), S) !=
              childGraph->end() &&
@@ -887,8 +913,8 @@ void DFInternalNode::addEdgeToDFGraph(DFEdge *E) {
   S->addOutDFEdge(E);
   D->addInDFEdge(E);
 
-  errs() << "SET SOURCE NODE: " << E->getSourceDF() << "\n";
-  errs() << "SET DEST NODE: " << E->getDestDF() << "\n";
+  //errs() << "SET SOURCE NODE: " << E->getSourceDF() << "\n";
+  //errs() << "SET DEST NODE: " << E->getDestDF() << "\n";
 
   // Update Rank
   if (D->getRank() <= S->getRank())
diff --git a/hpvm/include/SupportHPVM/HPVMHint.h b/hpvm/include/SupportHPVM/HPVMHint.h
index b83d09db1bd296c13447efb6e802c4d81c50c89f..7677b01ae2b05e74c6d0609df9ea5bbaf6e14ea9 100644
--- a/hpvm/include/SupportHPVM/HPVMHint.h
+++ b/hpvm/include/SupportHPVM/HPVMHint.h
@@ -20,6 +20,7 @@ enum Target {
   CPU_TARGET,
   GPU_TARGET,
   CUDNN_TARGET,
+  PROMISE_TARGET,
   CPU_OR_GPU_TARGET,
   //    ALL_TARGETS,
   NUM_TARGETS
diff --git a/hpvm/include/SupportHPVM/HPVMUtils.h b/hpvm/include/SupportHPVM/HPVMUtils.h
index 2242f9252f06731a7ee6746469f6753de5eefc2b..8df1af8310595e7a8b61f5978da693e6d31be92e 100644
--- a/hpvm/include/SupportHPVM/HPVMUtils.h
+++ b/hpvm/include/SupportHPVM/HPVMUtils.h
@@ -128,6 +128,7 @@ void fixHintMetadata(Module &M, Function *F, Function *G) {
   FixHint("hpvm_hint_cpu");
   FixHint("hpvm_hint_cpu_gpu");
   FixHint("hpvm_hint_cudnn");
+  FixHint("hpvm_hint_promise");
 }
 
 // Assuming that the changed function is a node function, it is only used as a
@@ -397,19 +398,24 @@ bool tagIncludesTarget(hpvm::Target Tag, hpvm::Target T) {
       if (T == hpvm::CUDNN_TARGET)
         return true;
       return false;
+  case hpvm::PROMISE_TARGET:
+      if (T == hpvm::PROMISE_TARGET)
+        return true;
+      return false;
   default:
     assert(false && "Unknown Target\n");
   }
 }
 
 bool isSingleTargetTag(hpvm::Target T) {
-  return ((T == hpvm::CPU_TARGET) || (T == hpvm::GPU_TARGET) || (T == hpvm::CUDNN_TARGET));
+  return ((T == hpvm::CPU_TARGET) || (T == hpvm::GPU_TARGET) 
+       || (T == hpvm::CUDNN_TARGET) || (T == hpvm::PROMISE_TARGET));
 }
 
 // Add the specified target to the given tag
 hpvm::Target getUpdatedTag(hpvm::Target Tag, hpvm::Target T) {
   assert(((T == hpvm::CPU_TARGET) || (T == hpvm::GPU_TARGET) 
-       || (T == hpvm::CUDNN_TARGET)) &&
+       || (T == hpvm::CUDNN_TARGET) || (T == hpvm::PROMISE_TARGET)) &&
          "The target is only allowed to be a single target: CPU, GPU, SPIR, "
          "CUDNN, PROMISE\n");
 
@@ -417,21 +423,21 @@ hpvm::Target getUpdatedTag(hpvm::Target Tag, hpvm::Target T) {
   case hpvm::None:
     return T;
   case hpvm::CPU_TARGET:
-    assert((T != hpvm::CUDNN_TARGET) && "Unsupported target combination\n");
+    assert((T != hpvm::CUDNN_TARGET) && (T != hpvm::PROMISE_TARGET) && "Unsupported target combination\n");
     if (T == hpvm::CPU_TARGET)
       return hpvm::CPU_TARGET;
     if (T == hpvm::GPU_TARGET)
       return hpvm::CPU_OR_GPU_TARGET;
     return T;
   case hpvm::GPU_TARGET:
-    assert((T != hpvm::CUDNN_TARGET) && "Unsupported target combination\n");
+    assert((T != hpvm::CUDNN_TARGET) && (T != hpvm::PROMISE_TARGET) && "Unsupported target combination\n");
     if (T == hpvm::CPU_TARGET)
       return hpvm::CPU_OR_GPU_TARGET;
     if (T == hpvm::GPU_TARGET)
       return hpvm::GPU_TARGET;
     return T;
   case hpvm::CPU_OR_GPU_TARGET:
-    assert((T != hpvm::CUDNN_TARGET) && "Unsupported target combination\n");
+    assert((T != hpvm::CUDNN_TARGET) && (T != hpvm::PROMISE_TARGET) && "Unsupported target combination\n");
     return hpvm::CPU_OR_GPU_TARGET; 
   default:
     assert(false && "Unknown Target\n");
@@ -441,6 +447,7 @@ hpvm::Target getUpdatedTag(hpvm::Target Tag, hpvm::Target T) {
 
 // This functions add the hint as metadata in hpvm code
 void addHint(Function *F, hpvm::Target T) {
+  errs() << "ADD HINT *************************\n";
   // Get Module
   Module *M = F->getParent();
   DEBUG(errs() << "Set preferred target for " << F->getName() << ": ");
@@ -464,6 +471,11 @@ void addHint(Function *F, hpvm::Target T) {
       DEBUG(errs() << "CUDNN Target\n");
       HintNode = M->getOrInsertNamedMetadata("hpvm_hint_cudnn");
       break;
+  case hpvm::PROMISE_TARGET:
+      DEBUG(errs() << "PROMISE Target\n");
+      errs() << "PROMISE\n";
+      HintNode = M->getOrInsertNamedMetadata("hpvm_hint_promise");
+      break;
   default:
     llvm_unreachable("Unsupported Target Hint!");
     break;
@@ -497,6 +509,9 @@ void removeHint(Function *F, hpvm::Target T) {
   case hpvm::CUDNN_TARGET:
       HintNode = M->getOrInsertNamedMetadata("hpvm_hint_cudnn");
       break;
+  case hpvm::PROMISE_TARGET:
+      HintNode = M->getOrInsertNamedMetadata("hpvm_hint_promise");
+      break;
   default:
     llvm_unreachable("Unsupported Target Hint!");
     break;
@@ -546,6 +561,8 @@ hpvm::Target getPreferredTarget(Function *F) {
     return hpvm::CPU_OR_GPU_TARGET;
   if (FoundPrefTarget("hpvm_hint_cudnn"))
     return hpvm::CUDNN_TARGET;
+  if (FoundPrefTarget("hpvm_hint_promise"))
+    return hpvm::PROMISE_TARGET;
   return hpvm::None;
 }