diff --git a/hpvm/projects/hetero-c++/include/DFGUtils.h b/hpvm/projects/hetero-c++/include/DFGUtils.h
index c2f90c39d123b1fb458b76c870d7024a999e5d51..95f0dbfff22ed33bc1adaccebff773cd54138204 100644
--- a/hpvm/projects/hetero-c++/include/DFGUtils.h
+++ b/hpvm/projects/hetero-c++/include/DFGUtils.h
@@ -134,3 +134,6 @@ bool isPrivCall(CallInst* CI);
 
 bool isNonZeroCall(CallInst* CI);
 Value* castIntegerToBitwidth(Value* V, Instruction* InsertBefore, int BV);
+
+
+bool isHPVMGraphIntrinsic(Value* V);
diff --git a/hpvm/projects/hetero-c++/include/HPVMCGenFunctions.h b/hpvm/projects/hetero-c++/include/HPVMCGenFunctions.h
index caa9311476f59f82c7b62d6163a7275c2e752b82..d2e9928b814d0c20e8f587a9440b1693232efd64 100644
--- a/hpvm/projects/hetero-c++/include/HPVMCGenFunctions.h
+++ b/hpvm/projects/hetero-c++/include/HPVMCGenFunctions.h
@@ -103,7 +103,7 @@ class HPVMCGenGetNumNodeInstances : public HPVMCGenBase {
   public:
   HPVMCGenGetNumNodeInstances(HPVMCGenContext & HCGC) : HPVMCGenBase(HCGC) { }
 
-  CallInst* insertCall(Instruction* InsertPoint, Argument * Node, unsigned dimension);
+  CallInst* insertCall(Instruction* InsertPoint, Value * Node, unsigned dimension);
 };
 
 class HPVMCGenLaunch : public HPVMCGenBase {
diff --git a/hpvm/projects/hetero-c++/lib/DFGUtils.cpp b/hpvm/projects/hetero-c++/lib/DFGUtils.cpp
index 63be8a449cf49fc92da330053421be257127d556..a1747b5329abda5f64094bff1a8a287a680e2e83 100644
--- a/hpvm/projects/hetero-c++/lib/DFGUtils.cpp
+++ b/hpvm/projects/hetero-c++/lib/DFGUtils.cpp
@@ -1302,4 +1302,27 @@ Value* castIntegerToBitwidth(Value* V, Instruction* InsertBefore, int BV){
 }
 
 
+bool isHPVMGraphIntrinsic(Value* V){
+    CallInst* CI = dyn_cast<CallInst>(V);
+    if(!CI) return false;
+
+    Function* CF = CI->getCalledFunction();
+
+    if(!CF) return false;
+
+    if(isTaskBeginMarker(CI)) return true;
+    if(isParallelLoopMarker(CI)) return true;
+    if(isLaunchBeginMarker(CI)) return true;
+
+
+
+    if(CF->getName().str() == "__hpvm__attributes" || CF->getName().str() == "__hpvm__return" 
+        || CF->getName().str() == "__hpvm__order"
+            ){
+        return true;
+    }
+
+    return false;
+
+}
 
diff --git a/hpvm/projects/hetero-c++/lib/HPVMCGenFunctions.cpp b/hpvm/projects/hetero-c++/lib/HPVMCGenFunctions.cpp
index 5fe4bae961b80f396b3a6ddcdda0c46c54a70a86..8c4a450d5a7854b47f6942fb4240588ba1ee6e05 100644
--- a/hpvm/projects/hetero-c++/lib/HPVMCGenFunctions.cpp
+++ b/hpvm/projects/hetero-c++/lib/HPVMCGenFunctions.cpp
@@ -314,27 +314,28 @@ CallInst *HPVMCGenGetNodeInstanceID::insertCall(Instruction* InsertPoint, Value
     return NewCall;
 }
 
-CallInst *HPVMCGenGetNumNodeInstances::insertCall(Instruction* InsertPoint, Argument * Node, unsigned dimension) {
+CallInst *HPVMCGenGetNumNodeInstances::insertCall(Instruction* InsertPoint, Value * Node, unsigned dimension) {
     if(dimension > 2) {
         HPVMFatalError("Detected invalid dimension: " + std::to_string(dimension));
     }
 
-    char dim;
+    std::string dim;
     switch(dimension) {
         case 0:
-            dim = 'x';
+            dim = "__hpvm__getNumNodeInstances_x";
             break;
         
         case 1:
-            dim = 'y';
+            dim = "__hpvm__getNumNodeInstances_y";
             break;
 
         case 2:
-            dim = 'z';
+            dim = "__hpvm__getNumNodeInstances_z";
             break;
     }
 
-    const StringRef FuncName("__hpvm__getNumNodeInstances_" + dim);
+
+    const StringRef FuncName(dim);
     Function * HpvmGetNode = theContext.getModule().getFunction(FuncName);
     if (!HpvmGetNode) {
         HPVMFatalError("__hpvm__getNumNodeInstances function not found in context");
diff --git a/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp b/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp
index a751d0ec8e744c9a33ecff2e03ed62784279132f..0edd768a3fac23184b5c390bb7814e94b39314df 100644
--- a/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp
+++ b/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp
@@ -2856,13 +2856,17 @@ CallInst* HPVMProgram::parallelizeLoop(/*Loop* ExtractedLoop, Loop* InnerLoop*/
     HPVMCGenContext cgenContext(M);
     HPVMCGenGetNode cgenGetNode(cgenContext);
     HPVMCGenGetNodeInstanceID cgenGetID(cgenContext);
+    HPVMCGenGetNumNodeInstances cgenGetNumNode(cgenContext);
 
     CallInst* getNodeCall = cgenGetNode.insertCall(OrigF->getEntryBlock().getTerminator());
 
     for(int i = 0; i < Limits.size(); i++){
         CallInst* getIDCall = cgenGetID.insertCall(OrigF->getEntryBlock().getTerminator(),
             getNodeCall, i);
-        
+
+        CallInst* getNumCall = cgenGetNumNode.insertCall(OrigF->getEntryBlock().getTerminator(),
+            getNodeCall, i);
+
         Value* InductionVar = InductionVars[i];
 
         Loop* L = LoopNest[i];
@@ -2954,7 +2958,7 @@ CallInst* HPVMProgram::parallelizeLoop(/*Loop* ExtractedLoop, Loop* InnerLoop*/
         Value* MatchedType = castIntegerToBitwidth(getIDCall, getIDCall->getNextNode(), IVTy->getBitWidth());
 
 
-        auto shouldReplace = [&](Use &U)->bool {
+        auto shouldReplaceIV = [&](Use &U)->bool {
             auto useInst = U.getUser();
             Instruction* IU = dyn_cast<Instruction>(useInst);
 
@@ -2965,12 +2969,38 @@ CallInst* HPVMProgram::parallelizeLoop(/*Loop* ExtractedLoop, Loop* InnerLoop*/
 
         };
 
-        InductionVar->replaceUsesWithIf(MatchedType, shouldReplace);
+
+        InductionVar->replaceUsesWithIf(MatchedType, shouldReplaceIV);
 
         cast<Instruction>(InductionVar)->eraseFromParent();
 
 
 
+        IntegerType* LimTy = dyn_cast<IntegerType>(InductionVar->getType());
+        assert(LimTy && "Loop bounds  must be of integer type");
+
+        Value* MatchedLimitType = castIntegerToBitwidth(getNumCall, getNumCall->getNextNode(), LimTy->getBitWidth());
+
+        auto shouldReplaceLimit = [&](Use &U)->bool {
+            auto useInst = U.getUser();
+            Instruction* IU = dyn_cast<Instruction>(useInst);
+
+            if(!IU) return false;
+            if(IU->getParent()->getParent() != OrigF) return false;
+            if(isHPVMGraphIntrinsic(IU)) return false;
+
+            Instruction* LimInst = dyn_cast<Instruction>(MatchedLimitType);
+
+            return IU && DTCache.dominates(LimInst, IU);
+
+        };
+
+
+        Limits[i]->replaceUsesWithIf(MatchedLimitType, shouldReplaceLimit);
+
+
+
+
         LLVM_DEBUG(errs()<<"Transformed Function: "<<*OrigF<<"\n");