From 3d385817095fbb70c04b45d38d345e472ba2a0cc Mon Sep 17 00:00:00 2001
From: akashk4 <akashk4@illinois.edu>
Date: Wed, 8 Jan 2020 13:00:43 -0600
Subject: [PATCH] Define the clone function with additional args -- partially
 tested

---
 hpvm/include/SupportVISC/VISCUtils.h | 60 ++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/hpvm/include/SupportVISC/VISCUtils.h b/hpvm/include/SupportVISC/VISCUtils.h
index 02a44518ee..109a8cee8c 100644
--- a/hpvm/include/SupportVISC/VISCUtils.h
+++ b/hpvm/include/SupportVISC/VISCUtils.h
@@ -323,6 +323,66 @@ Function* cloneFunction(Function* F, FunctionType* newFT, bool
   return newF;
 }
 
+// Overloaded version of cloneFunction
+Function *cloneFunction(Function *F, Function *newF,
+			bool isAddingPtrSizeArg,
+                        SmallVectorImpl<ReturnInst *> *Returns = NULL) {
+
+  DEBUG(errs() << "Cloning Function: " << F->getName() << "\n");
+  DEBUG(errs() << "Old Function Type: " << *F->getFunctionType() << "\n");
+  DEBUG(errs() << "New Function Type: " << *newF->getFunctionType() << "\n");
+
+  assert(F->getFunctionType()->getNumParams() <=
+         newF->getFunctionType()->getNumParams() &&
+         "This function assumes that the new function has more arguments than "
+         "the old function!");
+
+  // Create Function of specified type
+  DEBUG(errs() << "Old Function name: " << F->getName() << "\n");
+  DEBUG(errs() << "New Function name: " << newF->getName() << "\n");
+  ValueToValueMapTy VMap;
+  DEBUG(errs() << "No value map provided. Creating default value map\n");
+  if(isAddingPtrSizeArg) {
+    DEBUG(errs() << "Case 1: Pointer arg followed by a i64 size argument in new function\n");
+    Function::arg_iterator new_ai = newF->arg_begin();
+    for(Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+        ai != ae; ++ai) {
+      DEBUG(errs() << ai->getArgNo() << ". " << *ai << " : " << *new_ai << "\n");
+      assert(ai->getType() == new_ai->getType() && "Arguments type do not match!");
+      VMap[&*ai] = &*new_ai;
+      new_ai->takeName(&*ai);
+      if(ai->getType()->isPointerTy()) {
+        std::string oldName = new_ai->getName();
+        // If the current argument is pointer type, the next argument in new
+        // function would be an i64 type containing the data size of this
+        // argument. Hence, skip the next arguement in new function.
+        ++new_ai;
+        new_ai->setName("bytes_"+oldName);
+      }
+      ++new_ai;
+    }
+  }
+  else {
+    DEBUG(errs() << "Case 2: Extra arguments are added at the end of old function\n");
+    Function::arg_iterator new_ai = newF->arg_begin();
+    for(Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+        ai != ae; ++ai, ++new_ai) {
+      DEBUG(errs() << ai->getArgNo() << ". " << *ai << " : " << *new_ai << "\n");
+      assert(ai->getType() == new_ai->getType() && "Arguments type do not match!");
+      VMap[&*ai] = &*new_ai;
+      new_ai->takeName(&*ai);
+    }
+  }
+
+  // Clone function
+  if (Returns == NULL)
+    Returns = new SmallVector<ReturnInst*, 8>();
+  CloneFunctionInto(newF, F, VMap, false, *Returns);
+
+  return newF;
+}
+
+
  //------------------- Helper Functions For Handling Hints -------------------//
   
 // Return true if 1st arg (tag) contains 2nd (target)
-- 
GitLab