[llvm-dev] Replacing a function from one module into another one

Philip Pfaffe via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 6 05:08:28 PDT 2018


Is the source function referencing global variables? You'll have to move
those too.

Cheers,
Philip

On Thu, Sep 6, 2018 at 1:07 PM Daniel Moya <danielmscr1994 at gmail.com> wrote:

> Hi Philip,
>
> The error happens when the program finishes and it automatically calls the
> destructors, so it is not an error specifically inside my program. Here's
> the full code:
>
> #include "llvm/ExecutionEngine/ExecutionEngine.h"
> #include "llvm/ExecutionEngine/MCJIT.h"
> #include "llvm/IRReader/IRReader.h"
> #include "llvm/Support/TargetSelect.h"
> #include "llvm/Support/SourceMgr.h"
> #include "llvm/Support/CodeGen.h"
> #include "llvm/Transforms/Utils/Cloning.h"
> #include "llvm/Transforms/Utils/ValueMapper.h"
> #include <iostream>
> #include <string.h>
>
> const std::string originalFileName = "tracer.ll";
> const std::string referenceFileName = "tracer_ref.ll";
>
> void populateVMap(llvm::ValueToValueMapTy &VMap, llvm::Function *fOld,
> llvm::Function *fNew) {
>   llvm::Function::arg_iterator DestI = fOld->arg_begin();
>   for (llvm::Function::const_arg_iterator J = fNew->arg_begin(); J !=
> fNew->arg_end();
>        ++J) {
>     DestI->setName(J->getName());
>     VMap[&*J] = &*DestI++;
>   }
>
> void addFunction(llvm::Module *oMod, llvm::Module *nMod, std::string
> nFName, std::string oFName) {
>   llvm::Function *fNew = nMod->getFunction(nFName);
>   llvm::Function *fOld = oMod->getFunction(oFName);
>
>   fOld->dropAllReferences();
>   fOld->deleteBody();
>
>   llvm::ValueToValueMapTy VMap;
>   populateVMap(VMap, fOld, fNew);
>   bool ModuleArg = true;
>   llvm::SmallVector<llvm::ReturnInst*, 8> Returns;
>   llvm::CloneFunctionInto(fOld, fNew, VMap, ModuleArg, Returns);
>   if (fNew->hasPersonalityFn())
>      fOld->setPersonalityFn(llvm::MapValue(fNew->getPersonalityFn(),
> VMap));
> }
>
> void replaceFunctions(std::string oldFuncName, std::string newFuncName) {
>   llvm::SMDiagnostic origErr;
>   llvm::LLVMContext origContext;
>   std::unique_ptr<llvm::Module> origMod =
> (llvm::parseIRFile(originalFileName, origErr, origContext));
>   llvm::Module *origMod_copy = origMod.get();
>   llvm::SMDiagnostic refErr;
>   llvm::LLVMContext refContext;
>   std::unique_ptr<llvm::Module>
> refMod(llvm::parseIRFile(referenceFileName, refErr, refContext));
>   llvm::Module *refMod_copy = refMod.get();
>
>   addFunction(origMod_copy, refMod_copy, newFuncName, oldFuncName);
>   printModule(origMod_copy);
>   std::cout << "Finish\n"; // Make sure the program finished
>
> }
> int main() {
>   std::string oldFuncName = "foo2";
>   std::string newFuncName = "foo3";
>   replaceFunctions(oldFuncName, newFuncName);
>   return 0;
> }
>
>
> The complete error after printing the module (I know the error it's after
> the program's execution because the "Finish" is printed before):
>
> Finish
> While deleting: i32 %
> Use still stuck around after Def is destroyed:  %c = alloca i32, align 4
> Use still stuck around after Def is destroyed:  %b.addr = alloca i32,
> align 4
> Use still stuck around after Def is destroyed:  %a.addr = alloca i32,
> align 4
> step3F: /home/moydan00/Clang/llvm-clang-6.0.0/lib/IR/Value.cpp:88:
> llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value
> is destroyed!"' failed.
>
> The beginning of the foo2 function in the tracer.ll:
>
> define i32 @foo2(i32 %a, i32 %b) #0 {
> entry:
>   %a.addr = alloca i32, align 4
>   %b.addr = alloca i32, align 4
>   %c = alloca i32, align 4
>
> The beginning of the foo3 function in the tracer_ref.ll:
>
> define i32 @foo3(i32 %a, i32 %b) #0 {
> entry:
>   %a.addr = alloca i32, align 4
>   %b.addr = alloca i32, align 4
>   %c = alloca i32, align 4
>
> I know it's a little bit confusing since both foo2 and foo3 are almost
> identical, but from the error, I know that the instruction copied from foo3
> to foo2 are still referring to the arguments in foo3. If any other
> information is needed please tell me.
>
> Regards,
> Daniel Moya
>
>
> El jue., 6 de sep. de 2018 a la(s) 11:36, Philip Pfaffe (
> philip.pfaffe at gmail.com) escribió:
>
>> Hi Daniel,
>>
>> when and where are you getting that error? Can you paste the full code?
>>
>> Cheers,
>> Philip
>>
>> On Thu, Sep 6, 2018 at 2:11 AM Daniel Moya <danielmscr1994 at gmail.com>
>> wrote:
>>
>>> Hi Philip,
>>>
>>> Thanks for the reference, I was able to follow it and copy the code that
>>> I saw necessary, but I still have some issues (references are still not
>>> updated). I created the function:
>>>
>>> void populateVMap(llvm::ValueToValueMapTy &VMap, llvm::Function *fOld,
>>> llvm::Function *fNew) {
>>>   llvm::Function::arg_iterator DestI = fOld->arg_begin();
>>>   for (llvm::Function::const_arg_iterator J = fNew->arg_begin(); J !=
>>> fNew->arg_end();
>>>        ++J) {
>>>     DestI->setName(J->getName());
>>>     VMap[&*J] = &*DestI++;
>>>   }
>>> }
>>>
>>> The same as in *CloneModule*, then I have this code:
>>>
>>> llvm::Function *fNew = nMod->getFunction(nFName);
>>> llvm::Function *fOld = oMod->getFunction(oFName);
>>>
>>> fOld->dropAllReferences();
>>> fOld->deleteBody();
>>>
>>> llvm::ValueToValueMapTy VMap;
>>> populateVMap(VMap, fOld, fNew);
>>> bool ModuleArg = true;
>>> llvm::SmallVector<llvm::ReturnInst*, 8> Returns;
>>> llvm::CloneFunctionInto(fOld, fNew, VMap, ModuleArg, Returns);
>>> if (fNew->hasPersonalityFn())
>>>    fOld->setPersonalityFn(llvm::MapValue(fNew->getPersonalityFn(),
>>> VMap));
>>>
>>> But after running the code, I still get the error: *Use still stuck
>>> around after Def is destroyed*
>>>
>>> Which means that the instructions moved from *fNew* still refer to the
>>> arguments of *fNew* instead of the "mapped" (supposedly) ones in *fOld*.
>>> I have some ideas of what could be going on:
>>>
>>>    1. I'm not populating correctly the VMap argument, although I
>>>    wouldn't know how to do it differently since I literally copied it from the
>>>    *CloneModule*.
>>>    2. I have to still add more instruction either before or after
>>>    *CloneFunctionInto*, for example in *CloneModule* they call the
>>>    function [copyComdat](*http://llvm.org/doxygen/CloneModule_8cpp.html#a04b8f04da3f1b0bf1c9a2802f73e2d05
>>>    <http://llvm.org/doxygen/CloneModule_8cpp.html#a04b8f04da3f1b0bf1c9a2802f73e2d05>*),
>>>    but I don't know if it's necessary (I guess no because it's only defined in
>>>    CloneModule.cpp), they also iterate over global alias and functions, but
>>>    since I'm only concerned in the arguments of one function, I guess I don't
>>>    have to worry about that.
>>>    3. Perhaps what you mentioned before "Only operations across
>>>    LLVMContexts are tricky" has something to do, because the operation is
>>>    between modules of different files, I'm guessing they have different
>>>    Contexts too, what could be done in this case?
>>>
>>> Finally, I also tried moving the BasicBlocks manually and got the same
>>> error "Use still stuck..", and then tried
>>> calling llvm::RemapFunction afterwards with the populated VMap, but always
>>> got the error:
>>>
>>> Assertion `(Flags & RF_IgnoreMissingLocals) && "Referenced value not in
>>> value map!"' failed
>>>
>>> Which left me clueless since the mapping worked in the
>>> *CloneFunctionInto* (the program executed fine, the error "Use still
>>> stuck" happened at the program's end) but not in this *RemapFunction*.
>>> Anyways, I believe *CloneFunctionInto* should do this remap work so I
>>> shouldn't have to call *RemapFunction*. Any guideline would be greatly
>>> appreciated, it has been a long suffering.
>>>
>>> Regards,
>>> Daniel Moya
>>>
>>>
>>> El mié., 5 de sep. de 2018 a la(s) 11:15, Philip Pfaffe (
>>> philip.pfaffe at gmail.com) escribió:
>>>
>>>> Hi Daniel,
>>>>
>>>> the implementation of [CloneModule](
>>>> http://llvm.org/doxygen/CloneModule_8cpp_source.html) should be a good
>>>> example. Generally all you need to do in your case is map old arguments to
>>>> new arguments.
>>>>
>>>> Cheers,
>>>> Philip
>>>>
>>>> On Tue, Sep 4, 2018 at 1:18 PM Daniel Moya <danielmscr1994 at gmail.com>
>>>> wrote:
>>>>
>>>>> 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/20180906/563f966b/attachment-0001.html>


More information about the llvm-dev mailing list