[llvm-dev] Copy Function from one LLVM IR file to another

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Copy Function from one LLVM IR file to another

Sudhindra kulkarni via llvm-dev
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<Module> 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<Module> 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.

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Copy Function from one LLVM IR file to another

Sudhindra kulkarni via llvm-dev
Hi,

On Fri, 17 May 2019 at 07:40, Kell Maresh via llvm-dev
<[hidden email]> wrote:
> 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.
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Copy Function from one LLVM IR file to another

Sudhindra kulkarni via llvm-dev
In reply to this post by Sudhindra kulkarni via llvm-dev


On Thu, May 16, 2019 at 11:40 PM Kell Maresh via llvm-dev <[hidden email]> wrote:
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.

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.

-- 
Mehdi



 

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

        SMDiagnostic Err;
        LLVMContext Context;

        std::unique_ptr<Module> 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<Module> 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.
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Copy Function from one LLVM IR file to another

Sudhindra kulkarni via llvm-dev
In reply to this post by Sudhindra kulkarni via llvm-dev
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.

On Fri, 17 May 2019 at 14:40, Tim Northover <[hidden email]> wrote:
Hi,

On Fri, 17 May 2019 at 07:40, Kell Maresh via llvm-dev
<[hidden email]> wrote:
> 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.

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Copy Function from one LLVM IR file to another

Sudhindra kulkarni via llvm-dev
Hi Kell,

On Sun, 19 May 2019 at 07:51, Kell Maresh <[hidden email]> wrote:
> 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.
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev