-->

Filling the LLVM CloneFunction VMAP

2019-08-10 11:58发布

问题:

I want to write some code that, given an LLVM function F, creates an exact copy in the same module (so the copy can be manipulated later while preserving the original). I want to do this with the CloneFunctionInto method.

My current attempt involves trying to insert each (new arg,old arg) pair into the VMap. Previously I've tried inserting an uninitialised VMap and putting the pair the other way round. Impressively, all 3 have resulted in the exact same error message:

Assertion `VMap.count(&I) && "No mapping from source argument specified!"' failed.

//F and S are defined higher up in the code
FunctionType *FType = F->getFunctionType();
Function *new_F = cast<Function>(M->getOrInsertFunction(S,FType));
std::vector<Type*> ArgTypes;
ValueToValueMapTy VMap;
Function::arg_iterator old_args = F->arg_begin();
for (Function::arg_iterator new_args = new_F->arg_begin(), new_args_end = new_F->arg_end();new_args != new_args_end; new_args++) {
  std::pair<Value*,Value*> pair(&*new_args,&*old_args);
  VMap.insert(pair);
  if (VMap.count(&*new_args)>0) {
   errs().write_escaped("Mapping added") << '\n';
  }
  old_args++;
 }
 SmallVector<ReturnInst*, 8> Returns;
 CloneFunctionInto(new_F, F, VMap, false, Returns, "_new", 0, 0);

In use, the 'mapping added' message is printed the correct number of times (i.e. once for each argument), so I'm really unsure where the error is.

回答1:

You can use CloneFunction instead of CloneFunctionInto when you just want to clone a function.

Also CloneFunction shows you how to handle a ValueToValueMap for cloning:

From CloneFunction.cpp:

00223 Function *llvm::CloneFunction(const Function *F, ValueToValueMapTy &VMap,
00224                               bool ModuleLevelChanges,
00225                               ClonedCodeInfo *CodeInfo) {
00226   std::vector<Type*> ArgTypes;
00227 
00228   // The user might be deleting arguments to the function by specifying them in
00229   // the VMap.  If so, we need to not add the arguments to the arg ty vector
00230   //
00231   for (const Argument &I : F->args())
00232     if (VMap.count(&I) == 0) // Haven't mapped the argument to anything yet?
00233       ArgTypes.push_back(I.getType());
00234 
00235   // Create a new function type...
00236   FunctionType *FTy = FunctionType::get(F->getFunctionType()->getReturnType(),
00237                                     ArgTypes, F->getFunctionType()->isVarArg());
00238 
00239   // Create the new function...
00240   Function *NewF = Function::Create(FTy, F->getLinkage(), F->getName());
00241 
00242   // Loop over the arguments, copying the names of the mapped arguments over...
00243   Function::arg_iterator DestI = NewF->arg_begin();
00244   for (const Argument & I : F->args())
00245     if (VMap.count(&I) == 0) {     // Is this argument preserved?
00246       DestI->setName(I.getName()); // Copy the name over...
00247       VMap[&I] = &*DestI++;        // Add mapping to VMap
00248     }
00249 
00250   if (ModuleLevelChanges)
00251     CloneDebugInfoMetadata(NewF, F, VMap);
00252 
00253   SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
00254   CloneFunctionInto(NewF, F, VMap, ModuleLevelChanges, Returns, "", CodeInfo);
00255   return NewF;
00256 }