Copy Function from one LLVM IR file to another

Hello everyone,

I wanted to copy a function from one file to another. The file that I wanted to copy the function into contains a function with the same name and same number of instructions. I decided to just replace the instructions with those of the other function. I am doing all of this from within a function pass.

1. I created a function pass in which I extract a function using “llvm-extract” from within the pass.

2. Then I read the (.ll) file created by the “llvm-extract” tool using:

SMDiagnostic Err;
LLVMContext Context;

std::unique_ptr ParsedMod(parseIRFile(“add.ll”, Err, Context));
Module &M = dynamic_cast<Module&>(ParsedMod);
Module
Mod_ptr = &M;

3. Then I read the (.ll) file into which I want to copy the function using:

std::unique_ptr ParsedMod2(parseIRFile(“server.ll”, Err, Context));
Module &M2 = dynamic_cast<Module&>(ParsedMod2);
Module
Mod_ptr2 = &M2;

4. I keep two iterators to save the points from where i have to start replacing instructions as:

Module::iterator F1;
Module::iterator F2;

5. Assign them values so that F1 points to the first function and F2 to the second function:

for(Module::iterator func = Mod_ptr->begin(), Lfunc = Mod_ptr->end(); func!=Lfunc; ++func)
{
F1 = func;
}

for(Module::iterator func2 = Mod_ptr2->begin(), Lfunc2 = Mod_ptr2->end(); func2!=Lfunc2; ++func2)
{
if(func2->getName() == F.getName()) //F.getName() gives the same name as the function that was extracted
{
F2 = func2;
}
}

6. Replacing each instruction of F2 with instruction from F1 using:

for(Function::iterator bb = F1->begin(), Lbb = F1->end(), bb2 = F2->begin(), Lbb2 = F2->end(); bb2!=Lbb2; ++bb, ++bb2)
{
for(BasicBlock::iterator inst = bb->begin(), Linst = bb->end(), inst2 = bb2->begin(), Linst2 = bb2->end(); inst2 != Linst2; ++inst, ++inst2)
{
Instruction* I = &inst;
Instruction
I2 = &*inst2;

//errs() << "F1’s instruction: " << *I << “\n”;
//errs() << "F2’s instruction: " << *I2 << “\n”;

ReplaceInstWithInst(I, I2);
}
}

If I comment the ReplaceInstWithInst instruction and uncomment the instructions printing the instructions from two functions, correct instructions are printed.

I get Segmentation Fault if I use ReplaceInstWithInst instruction.

Hi,

2. Then I read the (.ll) file created by the "llvm-extract" tool using:

That seems a bit pointless.

I get Segmentation Fault if I use ReplaceInstWithInst instruction.

At the very least, I think doing that replacement will disrupt the
iterator going through the source function because it has to remove
the instruction. But just because two functions have the same number
of instructions doesn't mean they can be replaced one at a time in a
compatible manner. That would only work if the type of every
instruction matches up perfectly too.

What you should probably be doing is erasing the body of the new
function entirely and cloning the instructions into it. You could roll
your own cloning code, but there are helpers already written to do it
properly in include/llvm/Transforms/Utils/Cloning.h. CloneFunctionInto
looks especially relevant to your situation.

Cheers.

Tim.

If you already go the llvm-extract route, you may want to look at llvm-cat and/or llvm-link which should accomplish what you’re trying to do manually below.

Hi,
Thanks a lot for your response. I was successfully able to use CloneFunctionInto for copying the function over when the number of arguments to both the functions are same. Can CloneFunctionInto be used when the number of arguments of the functions are not equal? If yes, how do I provide the ValueToValueMapTy &VMap argument to the CloneIntoFunction in that case? When the number of arguments of both functions are equal, the VMap is just a map from each of the function’s arguments to the other.

Hi Kell,

Thanks a lot for your response. I was successfully able to use CloneFunctionInto for copying the function over when the number of arguments to both the functions are same. Can CloneFunctionInto be used when the number of arguments of the functions are not equal? If yes, how do I provide the ValueToValueMapTy &VMap argument to the CloneIntoFunction in that case?

It's certainly possible, but how you map the arguments depends
entirely on how you want this new function to behave. They need to be
compatible in some way you understand for the operation to make any
sense at all, and that compatibility ought to tell you how to map the
arguments.

If actually making sense isn't important for some reason, you could
map all extra arguments to undef. But the resulting function shouldn't
be expected to do anything useful.

Cheers.

Tim.