[llvm-dev] Replacing a function from one module into another one
Daniel Moya via llvm-dev
llvm-dev at lists.llvm.org
Sun Sep 2 05:26:46 PDT 2018
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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180902/24afc7fa/attachment.html>
More information about the llvm-dev
mailing list