Daniel Moya via llvm-dev
2018-Sep-03 16:31 UTC
[llvm-dev] Replacing a function from one module into another one
Thank you Ahmad, I figured out that, although the type of both p(oInst) and p(nInst) were the same, I had to: for (unsigned int i = 0; i < callOInst->getNumArgOperands(); i++) { callOInst->getArgOperand(i)->mutateType(callNInst->getArgOperand(i)->getType()); } that solves the issue at the calling instruction in the main function, but now I see that *linkModules* does not work for me (it's a mess to bring all the other unnecessary functions from the reference module) so what I need is to directly move one function from one module to another one. I'm still facing the issue with the *llvm::SmallVectorImpl< llvm::ReturnInst *> &Returns *argument for the *CloneFunctionInto, *can anyone please give an example of use of that function? I guess that's the only way because otherwise if I move the blocks from foo3 in the refModule to the oldModule, the references of the moved block still point to the arguments of foo3 defined in the refModule, and I don't know how to go instruction by instruction in all the moved blocks and correct the reference to point to the arguments in the oldModule's new function, this also sounds very messy and complicated. Regards, Daniel Moya El dom., 2 de sep. de 2018 a la(s) 23:18, Ahmad Nouralizadeh Khorrami ( ahmad.llvm at gmail.com) escribió:> Hi Daniel, > The answer was for your first thread. The benefits are outlined in the > repository, but your problem is still there. I'm not sure. But this looks > similar to my recent problem. I think that a bitcast will solve the > problem. The types after the linking process may have different names but > the same contents. The links to the answers are as follows: > http://lists.llvm.org/pipermail/llvm-dev/2018-August/125413.html > > https://stackoverflow.com/questions/51894129/convert-function-pointer-call-to-function-call-at-the-ir-level > Regards. > > On Sun, 2 Sep 2018 at 23:30, Daniel Moya <danielmscr1994 at gmail.com> wrote: > >> Hi Ahmad, >> >> What does that tool does besides what LLVM linker already does? I don't >> think my problem is in linking both modules, I think LLVM linker does the >> job for me, the issue is when changing the called function to call another >> function (in the example previously provided, to change it from foo2 to >> foo3, and adjusting the function parameter's references). >> >> Regards, >> Daniel Moya >> >> El dom., 2 de sep. de 2018 a la(s) 17:00, Ahmad Nouralizadeh Khorrami ( >> ahmad.llvm at gmail.com) escribió: >> >>> Hi. >>> Besides the LLVM linker, you can also use this tool: >>> https://github.com/travitch/whole-program-llvm >>> It links all the modules and produces a single module containing every >>> function. >>> Regards. >>> >>> On Sun, 2 Sep 2018 at 16:57, Daniel Moya via llvm-dev < >>> llvm-dev at lists.llvm.org> wrote: >>> >>>> Hello and thanks for the answer, >>>> >>>> I'm still facing issues, I'll do my best to explain my situation, as I >>>> explained, I have two modules, each one with its own main and functions, I >>>> would like to replace in the *oldModule* a function call that is >>>> calling *foo2* (defined in *oldModule*) to instead call *foo3*, which >>>> is defined in the *refModule. *So in summary, I have: >>>> >>>> 1. The original instruction call, defined in the main function of >>>> the oldModule, who is a calling function to foo2, I'll name it >>>> *oInst *(original Instruction) >>>> 2. The "new" instruction call, defined in the main function of the >>>> refModule, who is a calling function to foo3, I'll name it *nInst* (new >>>> Instruction) >>>> 3. The foo2 function definition, defined in the oldModule, I'll >>>> name it *oFunc *(original Function) >>>> 4. The foo3 function definition, defined in the refModule, I'll >>>> name it *nFunc* (new Function) >>>> 5. I have the parameters (or arguments?) of both functions, both in >>>> the calling instruction and in the function's definition, which I'll refer >>>> to as *p(oInst)*, *p(nInst)*, *p(oFunc)*, *p(nFunc) *(the >>>> parameters of) >>>> 6. For testing purposes, both foo2 and foo3 and defined identical, >>>> same returning type, parameter's type and even the same variable's name in >>>> the IR. >>>> >>>> So after calling the *llvm::LinkerlinkModules* function, I did: >>>> >>>> 1. First attempt: >>>> >>>> 1. llvm::CallInst *callOInst >>>> static_cast<llvm::CallInst*>(oInst); // I cast the* oInst* to a >>>> llvm::CallInst >>>> 2. callOInst->setCalledFunction(nFunc); // now *oInst* should call >>>> nFunc >>>> >>>> Error: >>>> Call parameter type does not match function signature! >>>> %0 = load i32, i32* %a, align 4 >>>> i32 %call1 = call i32 @foo3(i32 %0, i32 %1) >>>> >>>> So even though the parameters are the same type, and defined >>>> identically in both modules, the *p(oInst)* apparently does not match >>>> the *p(nFunc)*. >>>> >>>> 2. Second attempt: >>>> >>>> 1. llvm::Instruction *nCloneInst = nInst->clone(); //Clone of the >>>> *nInst*, to avoid remove it from the refModule >>>> 2. nCloneInst->insertAfter(oInst); // I'll bring the nInst because >>>> I know *p(nInst)* and *p(nFunc)* match >>>> 3. nCloneInst->mutateType(oInst->getType()); //Idk why I have to >>>> this, but necessary for next line >>>> 4. oInst->replaceAllUsesWith(nCloneInst); >>>> 5. oInst->dropAllReferences(); >>>> 6. oInst->eraseFromParent(); >>>> >>>> Error: >>>> Instruction does not dominate all uses! >>>> %0 = load i32, i32* %a, align 4 >>>> %2 = call i32 @foo3(i32 %0, i32 %1) >>>> >>>> Great, now the *p(nInst)* are still referring to their definition in >>>> the refModule, so either I bring those instructions too (which sounds >>>> really messy) or somehow I change the *p(nInst)* to refer to the >>>> instructions in oldModule, which in my case are actually defined the same >>>> (but apparently the references don't change based on the name being the >>>> same in both modules). >>>> >>>> 3. Third attempt: >>>> >>>> 1. The same 1-4 steps as before, from cloning instruction to >>>> replaceAllUsesWith >>>> 2. llvm::CallInst *callNInst >>>> static_cast<llvm::CallInst*>(nCloneInst); >>>> 3. llvm::CallInst *callOInst = static_cast<llvm::CallInst*>(oInst); >>>> // cast both *oInst* and *nInst* >>>> 4. for (unsigned int i = 0; i < callOInst->getNumArgOperands(); >>>> i++) { callNInst->setArgOperand(i,callOInst->getArgOperand(i)); } //replace >>>> *p(nInst)* with *p(oInst)* >>>> 5. The same 5-6 steps as before, drop and erase >>>> >>>> Error: >>>> Call parameter type does not match function signature! >>>> %0 = load i32, i32* %a, align 4 >>>> i32 %2 = call i32 @foo3(i32 %0, i32 %1) >>>> >>>> So back to the first problem, the *p(nInst) *(now converted to >>>> *p(oInst)*) apparently does not match the *p(nFunc)*. >>>> >>>> I also looked into the *CloneFunctionInto *function, but I didn't >>>> understand the arguments of it, and there's really no documentation or >>>> examples that I could find on the internet. Specifically, I have troubles >>>> with *llvm::SmallVectorImpl< llvm::ReturnInst *> &Returns *argument, I >>>> don't know how to initialize it, it doesn't have a 0 argument constructor >>>> and if I try: >>>> >>>> llvm::SmallVectorImpl< llvm::ReturnInst *> ReturnsArg >>>> llvm::SmallVectorImpl< llvm::ReturnInst *>(2); // Just as an example >>>> >>>> It says that constructor is protected. I didn't want to go further >>>> since I'm clueless on how to properly use this function, and I'm even not >>>> completely sure if it would fix all the troubles that I've been having with >>>> the other three attempts. >>>> >>>> Btw, all these errors happen when I try to run (through JIT) the >>>> module, a workaround that I know that I can do for all my attempts is just >>>> to dump the module to a file, and then reload it and execute it (I know it >>>> works since in both oldModule and refModule I use the same IR variable's >>>> names) but I would like to do the work the *right* way and not having >>>> to inefficiently dump a file just to reload it again and get all the >>>> references right. >>>> >>>> Thanks for the help in advance, I'll be really grateful for any advice >>>> or light in my situation. >>>> >>>> Regards, >>>> Daniel Moya >>>> >>>> >>>> >>>> >>>> >>>> >>>> El mar., 28 de ago. de 2018 a la(s) 20:26, Friedman, Eli ( >>>> efriedma at codeaurora.org) escribió: >>>> >>>>> On 8/27/2018 10:37 AM, Daniel Moya via llvm-dev wrote: >>>>> > Hello LLVM Developers, >>>>> > >>>>> > I'm trying to replace a function defined in one module into another >>>>> > module (different files). The first issue I ran into was that >>>>> > llvm::Function does not have a method "moveBefore" or "moveAfter" as >>>>> > the llvm::BasicBlock or llvm::Instruction do, so I figured I would >>>>> > just move the BasicBlocks of the replacing function into the >>>>> function >>>>> > that was being replaced, and then eliminate the original BasicBlocks. >>>>> >>>>> Cross-module operations are tricky in general; I'd suggest using the >>>>> Linker::linkModules API if possible. >>>>> >>>>> -Eli >>>>> >>>>> -- >>>>> Employee of Qualcomm Innovation Center, Inc. >>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a >>>>> Linux Foundation Collaborative Project >>>>> >>>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> llvm-dev at lists.llvm.org >>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>> >>>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180903/4cb90532/attachment-0001.html>
Philip Pfaffe via llvm-dev
2018-Sep-03 16:41 UTC
[llvm-dev] Replacing a function from one module into another one
Hi Daniel, CloneFunctionInto wants to tell you about the new ReturnInstructions it produced, you're expected to pass a vector for this purpose. You're free to ignore these values, though, but you still have to pass that vector: SmallVector<ReturnInst*, 8> Returns; For the argument remapping, you're supposed to pre-populate the VMap you pass with the appropriate argument-to-argument mapping. It's perfectly fine to use CloneFunctionInto across modules, btw. Only operations across LLVMContexts are tricky. Cheers, Philip On Mon, Sep 3, 2018 at 6:31 PM Daniel Moya via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Thank you Ahmad, > > I figured out that, although the type of both p(oInst) and p(nInst) were > the same, I had to: > > for (unsigned int i = 0; i < callOInst->getNumArgOperands(); i++) { > callOInst->getArgOperand(i)->mutateType(callNInst->getArgOperand(i)->getType()); > } > > that solves the issue at the calling instruction in the main function, but > now I see that *linkModules* does not work for me (it's a mess to bring > all the other unnecessary functions from the reference module) so what I > need is to directly move one function from one module to another one. I'm > still facing the issue with the *llvm::SmallVectorImpl< llvm::ReturnInst > *> &Returns *argument for the *CloneFunctionInto, *can anyone please give > an example of use of that function? I guess that's the only way because > otherwise if I move the blocks from foo3 in the refModule to the oldModule, > the references of the moved block still point to the arguments of foo3 > defined in the refModule, and I don't know how to go instruction by > instruction in all the moved blocks and correct the reference to point to > the arguments in the oldModule's new function, this also sounds very messy > and complicated. > > > Regards, > Daniel Moya > > > > > El dom., 2 de sep. de 2018 a la(s) 23:18, Ahmad Nouralizadeh Khorrami ( > ahmad.llvm at gmail.com) escribió: > >> Hi Daniel, >> The answer was for your first thread. The benefits are outlined in the >> repository, but your problem is still there. I'm not sure. But this looks >> similar to my recent problem. I think that a bitcast will solve the >> problem. The types after the linking process may have different names but >> the same contents. The links to the answers are as follows: >> http://lists.llvm.org/pipermail/llvm-dev/2018-August/125413.html >> >> https://stackoverflow.com/questions/51894129/convert-function-pointer-call-to-function-call-at-the-ir-level >> Regards. >> >> On Sun, 2 Sep 2018 at 23:30, Daniel Moya <danielmscr1994 at gmail.com> >> wrote: >> >>> Hi Ahmad, >>> >>> What does that tool does besides what LLVM linker already does? I don't >>> think my problem is in linking both modules, I think LLVM linker does the >>> job for me, the issue is when changing the called function to call another >>> function (in the example previously provided, to change it from foo2 to >>> foo3, and adjusting the function parameter's references). >>> >>> Regards, >>> Daniel Moya >>> >>> El dom., 2 de sep. de 2018 a la(s) 17:00, Ahmad Nouralizadeh Khorrami ( >>> ahmad.llvm at gmail.com) escribió: >>> >>>> Hi. >>>> Besides the LLVM linker, you can also use this tool: >>>> https://github.com/travitch/whole-program-llvm >>>> It links all the modules and produces a single module containing every >>>> function. >>>> Regards. >>>> >>>> On Sun, 2 Sep 2018 at 16:57, Daniel Moya via llvm-dev < >>>> llvm-dev at lists.llvm.org> wrote: >>>> >>>>> Hello and thanks for the answer, >>>>> >>>>> I'm still facing issues, I'll do my best to explain my situation, as I >>>>> explained, I have two modules, each one with its own main and functions, I >>>>> would like to replace in the *oldModule* a function call that is >>>>> calling *foo2* (defined in *oldModule*) to instead call *foo3*, which >>>>> is defined in the *refModule. *So in summary, I have: >>>>> >>>>> 1. The original instruction call, defined in the main function of >>>>> the oldModule, who is a calling function to foo2, I'll name it >>>>> *oInst *(original Instruction) >>>>> 2. The "new" instruction call, defined in the main function of the >>>>> refModule, who is a calling function to foo3, I'll name it *nInst* (new >>>>> Instruction) >>>>> 3. The foo2 function definition, defined in the oldModule, I'll >>>>> name it *oFunc *(original Function) >>>>> 4. The foo3 function definition, defined in the refModule, I'll >>>>> name it *nFunc* (new Function) >>>>> 5. I have the parameters (or arguments?) of both functions, both >>>>> in the calling instruction and in the function's definition, which I'll >>>>> refer to as *p(oInst)*, *p(nInst)*, *p(oFunc)*, *p(nFunc) *(the >>>>> parameters of) >>>>> 6. For testing purposes, both foo2 and foo3 and defined identical, >>>>> same returning type, parameter's type and even the same variable's name in >>>>> the IR. >>>>> >>>>> So after calling the *llvm::LinkerlinkModules* function, I did: >>>>> >>>>> 1. First attempt: >>>>> >>>>> 1. llvm::CallInst *callOInst >>>>> static_cast<llvm::CallInst*>(oInst); // I cast the* oInst* to a >>>>> llvm::CallInst >>>>> 2. callOInst->setCalledFunction(nFunc); // now *oInst* should call >>>>> nFunc >>>>> >>>>> Error: >>>>> Call parameter type does not match function signature! >>>>> %0 = load i32, i32* %a, align 4 >>>>> i32 %call1 = call i32 @foo3(i32 %0, i32 %1) >>>>> >>>>> So even though the parameters are the same type, and defined >>>>> identically in both modules, the *p(oInst)* apparently does not match >>>>> the *p(nFunc)*. >>>>> >>>>> 2. Second attempt: >>>>> >>>>> 1. llvm::Instruction *nCloneInst = nInst->clone(); //Clone of the >>>>> *nInst*, to avoid remove it from the refModule >>>>> 2. nCloneInst->insertAfter(oInst); // I'll bring the nInst because >>>>> I know *p(nInst)* and *p(nFunc)* match >>>>> 3. nCloneInst->mutateType(oInst->getType()); //Idk why I have to >>>>> this, but necessary for next line >>>>> 4. oInst->replaceAllUsesWith(nCloneInst); >>>>> 5. oInst->dropAllReferences(); >>>>> 6. oInst->eraseFromParent(); >>>>> >>>>> Error: >>>>> Instruction does not dominate all uses! >>>>> %0 = load i32, i32* %a, align 4 >>>>> %2 = call i32 @foo3(i32 %0, i32 %1) >>>>> >>>>> Great, now the *p(nInst)* are still referring to their definition in >>>>> the refModule, so either I bring those instructions too (which sounds >>>>> really messy) or somehow I change the *p(nInst)* to refer to the >>>>> instructions in oldModule, which in my case are actually defined the same >>>>> (but apparently the references don't change based on the name being the >>>>> same in both modules). >>>>> >>>>> 3. Third attempt: >>>>> >>>>> 1. The same 1-4 steps as before, from cloning instruction to >>>>> replaceAllUsesWith >>>>> 2. llvm::CallInst *callNInst >>>>> static_cast<llvm::CallInst*>(nCloneInst); >>>>> 3. llvm::CallInst *callOInst >>>>> static_cast<llvm::CallInst*>(oInst); // cast both *oInst* and >>>>> *nInst* >>>>> 4. for (unsigned int i = 0; i < callOInst->getNumArgOperands(); >>>>> i++) { callNInst->setArgOperand(i,callOInst->getArgOperand(i)); } //replace >>>>> *p(nInst)* with *p(oInst)* >>>>> 5. The same 5-6 steps as before, drop and erase >>>>> >>>>> Error: >>>>> Call parameter type does not match function signature! >>>>> %0 = load i32, i32* %a, align 4 >>>>> i32 %2 = call i32 @foo3(i32 %0, i32 %1) >>>>> >>>>> So back to the first problem, the *p(nInst) *(now converted to >>>>> *p(oInst)*) apparently does not match the *p(nFunc)*. >>>>> >>>>> I also looked into the *CloneFunctionInto *function, but I didn't >>>>> understand the arguments of it, and there's really no documentation or >>>>> examples that I could find on the internet. Specifically, I have troubles >>>>> with *llvm::SmallVectorImpl< llvm::ReturnInst *> &Returns *argument, >>>>> I don't know how to initialize it, it doesn't have a 0 argument constructor >>>>> and if I try: >>>>> >>>>> llvm::SmallVectorImpl< llvm::ReturnInst *> ReturnsArg >>>>> llvm::SmallVectorImpl< llvm::ReturnInst *>(2); // Just as an example >>>>> >>>>> It says that constructor is protected. I didn't want to go further >>>>> since I'm clueless on how to properly use this function, and I'm even not >>>>> completely sure if it would fix all the troubles that I've been having with >>>>> the other three attempts. >>>>> >>>>> Btw, all these errors happen when I try to run (through JIT) the >>>>> module, a workaround that I know that I can do for all my attempts is just >>>>> to dump the module to a file, and then reload it and execute it (I know it >>>>> works since in both oldModule and refModule I use the same IR variable's >>>>> names) but I would like to do the work the *right* way and not having >>>>> to inefficiently dump a file just to reload it again and get all the >>>>> references right. >>>>> >>>>> Thanks for the help in advance, I'll be really grateful for any advice >>>>> or light in my situation. >>>>> >>>>> Regards, >>>>> Daniel Moya >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> El mar., 28 de ago. de 2018 a la(s) 20:26, Friedman, Eli ( >>>>> efriedma at codeaurora.org) escribió: >>>>> >>>>>> On 8/27/2018 10:37 AM, Daniel Moya via llvm-dev wrote: >>>>>> > Hello LLVM Developers, >>>>>> > >>>>>> > I'm trying to replace a function defined in one module into another >>>>>> > module (different files). The first issue I ran into was that >>>>>> > llvm::Function does not have a method "moveBefore" or "moveAfter" >>>>>> as >>>>>> > the llvm::BasicBlock or llvm::Instruction do, so I figured I would >>>>>> > just move the BasicBlocks of the replacing function into the >>>>>> function >>>>>> > that was being replaced, and then eliminate the original >>>>>> BasicBlocks. >>>>>> >>>>>> Cross-module operations are tricky in general; I'd suggest using the >>>>>> Linker::linkModules API if possible. >>>>>> >>>>>> -Eli >>>>>> >>>>>> -- >>>>>> Employee of Qualcomm Innovation Center, Inc. >>>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a >>>>>> Linux Foundation Collaborative Project >>>>>> >>>>>> _______________________________________________ >>>>> LLVM Developers mailing list >>>>> llvm-dev at lists.llvm.org >>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>>> >>>> _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180903/573153b9/attachment.html>
Daniel Moya via llvm-dev
2018-Sep-04 11:18 UTC
[llvm-dev] Replacing a function from one module into another one
Hi Philip, Thank you very much for your answer, the vector declaration example worked. I'm pretty sure the ValueToValueMapTy is the last thing I need because I even saw there is another function that could help me llvm*:*:RemapFunction <http://llvm.org/doxygen/namespacellvm.html#addf0183e92893bdbcde00fc9091dda93>; but my problem is that I don't know how to populate the ValueToValueMapTy (VMap) and I couldn't find a single complete example on the internet. To begin with, as the name implies (and also from some errors that I got) the ValueToValueMapTy takes a std::pair<llvm::Value, llvm::Value>, but what I need is to map the arguments (llvm::Attribute) of both functions (the first argument of foo2 is equivalent to the first argument of foo3, and so on), however, apparently there's no transformation from a llvm::Attribute to a llvm::Value. I'm using the function getAttribute <http://llvm.org/doxygen/classllvm_1_1Function.html#ab2a5fc8baaee7e74dbe47d848508745a> (unsigned <http://llvm.org/doxygen/classunsigned.html> i, StringRef <http://llvm.org/doxygen/classllvm_1_1StringRef.html> Kind <http://llvm.org/doxygen/ARMAsmParser_8cpp.html#a5ec5335889cd241b0ccfd4e4e58cf52e> ) const <http://llvm.org/doxygen/AArch64PromoteConstant_8cpp.html#a90f8350fecae261c25be85d38b451bff> to get the attributes, but I don't even understand why is it required to give the StringRef <http://llvm.org/doxygen/classllvm_1_1StringRef.html> Kind <http://llvm.org/doxygen/ARMAsmParser_8cpp.html#a5ec5335889cd241b0ccfd4e4e58cf52e> if what I need is just the attribute of the function in the *i *position. I'm really thankful for the quick responses and for the attention received. Regards, Daniel Moya El lun., 3 de sep. de 2018 a la(s) 18:42, Philip Pfaffe ( philip.pfaffe at gmail.com) escribió:> Hi Daniel, > > CloneFunctionInto wants to tell you about the new ReturnInstructions it > produced, you're expected to pass a vector for this purpose. You're free to > ignore these values, though, but you still have to pass that > vector: SmallVector<ReturnInst*, 8> Returns; > > For the argument remapping, you're supposed to pre-populate the VMap you > pass with the appropriate argument-to-argument mapping. > > It's perfectly fine to use CloneFunctionInto across modules, btw. Only > operations across LLVMContexts are tricky. > > Cheers, > Philip > > On Mon, Sep 3, 2018 at 6:31 PM Daniel Moya via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Thank you Ahmad, >> >> I figured out that, although the type of both p(oInst) and p(nInst) were >> the same, I had to: >> >> for (unsigned int i = 0; i < callOInst->getNumArgOperands(); i++) { >> callOInst->getArgOperand(i)->mutateType(callNInst->getArgOperand(i)->getType()); >> } >> >> that solves the issue at the calling instruction in the main function, >> but now I see that *linkModules* does not work for me (it's a mess to >> bring all the other unnecessary functions from the reference module) so >> what I need is to directly move one function from one module to another >> one. I'm still facing the issue with the *llvm::SmallVectorImpl< >> llvm::ReturnInst *> &Returns *argument for the *CloneFunctionInto, *can >> anyone please give an example of use of that function? I guess that's the >> only way because otherwise if I move the blocks from foo3 in the refModule >> to the oldModule, the references of the moved block still point to the >> arguments of foo3 defined in the refModule, and I don't know how to go >> instruction by instruction in all the moved blocks and correct the >> reference to point to the arguments in the oldModule's new function, this >> also sounds very messy and complicated. >> >> >> Regards, >> Daniel Moya >> >> >> >> >> El dom., 2 de sep. de 2018 a la(s) 23:18, Ahmad Nouralizadeh Khorrami ( >> ahmad.llvm at gmail.com) escribió: >> >>> Hi Daniel, >>> The answer was for your first thread. The benefits are outlined in the >>> repository, but your problem is still there. I'm not sure. But this looks >>> similar to my recent problem. I think that a bitcast will solve the >>> problem. The types after the linking process may have different names but >>> the same contents. The links to the answers are as follows: >>> http://lists.llvm.org/pipermail/llvm-dev/2018-August/125413.html >>> >>> https://stackoverflow.com/questions/51894129/convert-function-pointer-call-to-function-call-at-the-ir-level >>> Regards. >>> >>> On Sun, 2 Sep 2018 at 23:30, Daniel Moya <danielmscr1994 at gmail.com> >>> wrote: >>> >>>> Hi Ahmad, >>>> >>>> What does that tool does besides what LLVM linker already does? I don't >>>> think my problem is in linking both modules, I think LLVM linker does the >>>> job for me, the issue is when changing the called function to call another >>>> function (in the example previously provided, to change it from foo2 to >>>> foo3, and adjusting the function parameter's references). >>>> >>>> Regards, >>>> Daniel Moya >>>> >>>> El dom., 2 de sep. de 2018 a la(s) 17:00, Ahmad Nouralizadeh Khorrami ( >>>> ahmad.llvm at gmail.com) escribió: >>>> >>>>> Hi. >>>>> Besides the LLVM linker, you can also use this tool: >>>>> https://github.com/travitch/whole-program-llvm >>>>> It links all the modules and produces a single module containing every >>>>> function. >>>>> Regards. >>>>> >>>>> On Sun, 2 Sep 2018 at 16:57, Daniel Moya via llvm-dev < >>>>> llvm-dev at lists.llvm.org> wrote: >>>>> >>>>>> Hello and thanks for the answer, >>>>>> >>>>>> I'm still facing issues, I'll do my best to explain my situation, as >>>>>> I explained, I have two modules, each one with its own main and functions, >>>>>> I would like to replace in the *oldModule* a function call that is >>>>>> calling *foo2* (defined in *oldModule*) to instead call *foo3*, >>>>>> which is defined in the *refModule. *So in summary, I have: >>>>>> >>>>>> 1. The original instruction call, defined in the main function of >>>>>> the oldModule, who is a calling function to foo2, I'll name it >>>>>> *oInst *(original Instruction) >>>>>> 2. The "new" instruction call, defined in the main function of >>>>>> the refModule, who is a calling function to foo3, I'll name it >>>>>> *nInst* (new Instruction) >>>>>> 3. The foo2 function definition, defined in the oldModule, I'll >>>>>> name it *oFunc *(original Function) >>>>>> 4. The foo3 function definition, defined in the refModule, I'll >>>>>> name it *nFunc* (new Function) >>>>>> 5. I have the parameters (or arguments?) of both functions, both >>>>>> in the calling instruction and in the function's definition, which I'll >>>>>> refer to as *p(oInst)*, *p(nInst)*, *p(oFunc)*, *p(nFunc) *(the >>>>>> parameters of) >>>>>> 6. For testing purposes, both foo2 and foo3 and defined >>>>>> identical, same returning type, parameter's type and even the same >>>>>> variable's name in the IR. >>>>>> >>>>>> So after calling the *llvm::LinkerlinkModules* function, I did: >>>>>> >>>>>> 1. First attempt: >>>>>> >>>>>> 1. llvm::CallInst *callOInst >>>>>> static_cast<llvm::CallInst*>(oInst); // I cast the* oInst* to a >>>>>> llvm::CallInst >>>>>> 2. callOInst->setCalledFunction(nFunc); // now *oInst* should >>>>>> call nFunc >>>>>> >>>>>> Error: >>>>>> Call parameter type does not match function signature! >>>>>> %0 = load i32, i32* %a, align 4 >>>>>> i32 %call1 = call i32 @foo3(i32 %0, i32 %1) >>>>>> >>>>>> So even though the parameters are the same type, and defined >>>>>> identically in both modules, the *p(oInst)* apparently does not >>>>>> match the *p(nFunc)*. >>>>>> >>>>>> 2. Second attempt: >>>>>> >>>>>> 1. llvm::Instruction *nCloneInst = nInst->clone(); //Clone of the >>>>>> *nInst*, to avoid remove it from the refModule >>>>>> 2. nCloneInst->insertAfter(oInst); // I'll bring the nInst >>>>>> because I know *p(nInst)* and *p(nFunc)* match >>>>>> 3. nCloneInst->mutateType(oInst->getType()); //Idk why I have to >>>>>> this, but necessary for next line >>>>>> 4. oInst->replaceAllUsesWith(nCloneInst); >>>>>> 5. oInst->dropAllReferences(); >>>>>> 6. oInst->eraseFromParent(); >>>>>> >>>>>> Error: >>>>>> Instruction does not dominate all uses! >>>>>> %0 = load i32, i32* %a, align 4 >>>>>> %2 = call i32 @foo3(i32 %0, i32 %1) >>>>>> >>>>>> Great, now the *p(nInst)* are still referring to their definition in >>>>>> the refModule, so either I bring those instructions too (which sounds >>>>>> really messy) or somehow I change the *p(nInst)* to refer to the >>>>>> instructions in oldModule, which in my case are actually defined the same >>>>>> (but apparently the references don't change based on the name being the >>>>>> same in both modules). >>>>>> >>>>>> 3. Third attempt: >>>>>> >>>>>> 1. The same 1-4 steps as before, from cloning instruction to >>>>>> replaceAllUsesWith >>>>>> 2. llvm::CallInst *callNInst >>>>>> static_cast<llvm::CallInst*>(nCloneInst); >>>>>> 3. llvm::CallInst *callOInst >>>>>> static_cast<llvm::CallInst*>(oInst); // cast both *oInst* and >>>>>> *nInst* >>>>>> 4. for (unsigned int i = 0; i < callOInst->getNumArgOperands(); >>>>>> i++) { callNInst->setArgOperand(i,callOInst->getArgOperand(i)); } //replace >>>>>> *p(nInst)* with *p(oInst)* >>>>>> 5. The same 5-6 steps as before, drop and erase >>>>>> >>>>>> Error: >>>>>> Call parameter type does not match function signature! >>>>>> %0 = load i32, i32* %a, align 4 >>>>>> i32 %2 = call i32 @foo3(i32 %0, i32 %1) >>>>>> >>>>>> So back to the first problem, the *p(nInst) *(now converted to >>>>>> *p(oInst)*) apparently does not match the *p(nFunc)*. >>>>>> >>>>>> I also looked into the *CloneFunctionInto *function, but I didn't >>>>>> understand the arguments of it, and there's really no documentation or >>>>>> examples that I could find on the internet. Specifically, I have troubles >>>>>> with *llvm::SmallVectorImpl< llvm::ReturnInst *> &Returns *argument, >>>>>> I don't know how to initialize it, it doesn't have a 0 argument constructor >>>>>> and if I try: >>>>>> >>>>>> llvm::SmallVectorImpl< llvm::ReturnInst *> ReturnsArg >>>>>> llvm::SmallVectorImpl< llvm::ReturnInst *>(2); // Just as an example >>>>>> >>>>>> It says that constructor is protected. I didn't want to go further >>>>>> since I'm clueless on how to properly use this function, and I'm even not >>>>>> completely sure if it would fix all the troubles that I've been having with >>>>>> the other three attempts. >>>>>> >>>>>> Btw, all these errors happen when I try to run (through JIT) the >>>>>> module, a workaround that I know that I can do for all my attempts is just >>>>>> to dump the module to a file, and then reload it and execute it (I know it >>>>>> works since in both oldModule and refModule I use the same IR variable's >>>>>> names) but I would like to do the work the *right* way and not >>>>>> having to inefficiently dump a file just to reload it again and get all the >>>>>> references right. >>>>>> >>>>>> Thanks for the help in advance, I'll be really grateful for any >>>>>> advice or light in my situation. >>>>>> >>>>>> Regards, >>>>>> Daniel Moya >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> El mar., 28 de ago. de 2018 a la(s) 20:26, Friedman, Eli ( >>>>>> efriedma at codeaurora.org) escribió: >>>>>> >>>>>>> On 8/27/2018 10:37 AM, Daniel Moya via llvm-dev wrote: >>>>>>> > Hello LLVM Developers, >>>>>>> > >>>>>>> > I'm trying to replace a function defined in one module into >>>>>>> another >>>>>>> > module (different files). The first issue I ran into was that >>>>>>> > llvm::Function does not have a method "moveBefore" or "moveAfter" >>>>>>> as >>>>>>> > the llvm::BasicBlock or llvm::Instruction do, so I figured I would >>>>>>> > just move the BasicBlocks of the replacing function into the >>>>>>> function >>>>>>> > that was being replaced, and then eliminate the original >>>>>>> BasicBlocks. >>>>>>> >>>>>>> Cross-module operations are tricky in general; I'd suggest using the >>>>>>> Linker::linkModules API if possible. >>>>>>> >>>>>>> -Eli >>>>>>> >>>>>>> -- >>>>>>> Employee of Qualcomm Innovation Center, Inc. >>>>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a >>>>>>> Linux Foundation Collaborative Project >>>>>>> >>>>>>> _______________________________________________ >>>>>> LLVM Developers mailing list >>>>>> llvm-dev at lists.llvm.org >>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>>>>> >>>>> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180904/bf369255/attachment.html>
Possibly Parallel Threads
- Replacing a function from one module into another one
- Replacing a function from one module into another one
- Replacing a function from one module into another one
- Replacing a function from one module into another one
- Replacing a function from one module into another one