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

Daniel Moya via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 6 05:33:04 PDT 2018


No, the source function (foo3 defined in tracer_ref.ll in this case) is
only referencing, inside its function body, to the arguments that it takes.
This could be a minimum-version of the tracer_ref.ll file:

; ModuleID = 'tracer_ref.c'
source_filename = "tracer_ref.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [11 x i8] c"C1 is: %d\0A\00", align 1
@.str.1 = private unnamed_addr constant [11 x i8] c"C2 is: %d\0A\00", align
1

; Function Attrs: noinline nounwind optnone uwtable
define i32 @main() #0 {
entry:
  %a = alloca i32, align 4
  %b = alloca i32, align 4
  store i32 7, i32* %a, align 4
  store i32 5, i32* %b, align 4
  %0 = load i32, i32* %a, align 4
  %1 = load i32, i32* %b, align 4
  %call1 = call i32 @foo3(i32 %0, i32 %1)
  store i32 %call1, i32* %c2, align 4
  %3 = load i32, i32* %c2, align 4
  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x
i8], [11 x i8]* @.str.1, i32 0, i32 0), i32 %3)
  ret i32 0
}

; Function Attrs: noinline nounwind optnone uwtable
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
  store i32 %a, i32* %a.addr, align 4
  store i32 %b, i32* %b.addr, align 4
  %0 = load i32, i32* %a.addr, align 4
  %1 = load i32, i32* %b.addr, align 4
  %mul = mul nsw i32 %0, %1
  store i32 %mul, i32* %c, align 4
  %2 = load i32, i32* %c, align 4
  %3 = load i32, i32* %b.addr, align 4
  %mul1 = mul nsw i32 %2, %3
  store i32 %mul1, i32* %c, align 4
  %4 = load i32, i32* %c, align 4
  %5 = load i32, i32* %a.addr, align 4
  %mul2 = mul nsw i32 %4, %5
  store i32 %mul2, i32* %c, align 4
  %6 = load i32, i32* %c, align 4
  ret i32 %6
}

attributes #0 = { noinline nounwind optnone uwtable
"correctly-rounded-divide-sqrt-fp-math"="false"
"disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-jump-tables"="false"
"no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false"
"no-trapping-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false"
"disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"no-signed-zeros-fp-math"="false" "no-trapping-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false"
"use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

The error happens with the first three instructions of *foo3*, and the
first two are a direct reference to the arguments of *foo3* (I don't know
why the error message includes the third instruction). There are *no*
global variables in both module files. Thanks for the quick responses, it
really helps.

Regards,
Daniel Moya

El jue., 6 de sep. de 2018 a la(s) 14:08, Philip Pfaffe (
philip.pfaffe at gmail.com) escribió:

> 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/b8dbf0d6/attachment.html>


More information about the llvm-dev mailing list