Yaron Keren
2014-Jun-29 03:48 UTC
[LLVMdev] Wrong behavior modifying and executing llvm::Function with JIT Engine
getFunction() -> getPointerToFunction() 2014-06-29 6:40 GMT+03:00 Yaron Keren <yaron.keren at gmail.com>:> Hi Adrian, > > freeMachineCodeForFunction is required but recompileAndLinkFunction is > not, > you can use getFunction() always. > > Try to M->dump() calling M->getFunction() where M is the Module *. > See if how the changes appear in the module dump as expected. > > Yaron > > > > > > 2014-06-29 5:56 GMT+03:00 Adrian Ortega <elfus0.1 at gmail.com>: > >> Hello, >> >> The problem I'm having is that I modify a function body by using >> 'Value::replaceAllUsesWith' and then execute it with the JIT engine several >> times but I always get the output from the first iteration for all the >> iterations. >> >> This is what I do: >> >> >> I generate the following 2 functions on the fly based on the FunctionType >> of the declaration below in C code. >> >> >> define i32 @get_int_5(i32, i32) #1 { >> ret i32 5 >> } >> >> define i32 @get_int_10(i32, i32) #1 { >> ret i32 10 >> } >> >> I have the following C code: >> >> >> // This is only a declaration >> // I use this FunctionType to generate the functions above >> int sum(int a, int b); >> >> int get_int() >> { >> return sum(a,b); >> } >> >> I replace the call to 'sum()' by calling Value::replaceAllUsesWith for >> one of the functions generated above, run with JIT. I checked the code >> generated and it actually changes the call from 'sum()' to 'get_int_5()' >> and I get a 5 as return value when I call the function with the JIT >> execution engine. >> >> Then I repeat the previous step using 'Value::replaceAllUsesWith' for the >> next function I generated and run it with JIT. Then again the code >> generated is what I expected, this time >> function call changes from 'sum()' to 'get_int_10()', however the problem >> is I get a 5 instead of a 10. >> >> I tried 'recompileAndLinkFunction' as well as >> 'freeMachineCodeForFunction' and I always get the return value from the >> first function, and not the second as I should even though the generated >> code that I dump() says that it has the correct function call. >> >> I am using version 3.4 for both clang and llvm. And also I'm using the >> JIT Engine and not the MCJIT. >> >> Do you have have any idea why the references or 'uses' changes are not >> reflected in the code JIT'ed ? >> >> Regards. >> >> >> >> >> >> >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140629/3c309c6f/attachment.html>
Adrian Ortega
2014-Jun-29 14:00 UTC
[LLVMdev] Wrong behavior modifying and executing llvm::Function with JIT Engine
I tried using 'getPointerToFunction()' and the correct function I
generated was called from C code, but when it runs inside the JIT engine
it always returns the value of the first function. I even tried to
'deleteBody()' and 'removeFromParent()' from the first function
generated, and still returns the first value.
I also tried using 'dump()' to see if the values where being updated.
This is the C code I run with the JIT engine:
#include <stdio.h>
int sum(int a, int b); // declaration
int get_int(int a, int b)
{
int x = sum(a,b);
printf("The result was: %d\n",x);
return x;
}
As you can see I print the return value of the function. The functions I
generate and that I called 'get_int_*()' in the previous email are now
called 'sum_mockup_N()'. This is the code LLVM IR code:
; Function Attrs: nounwind uwtable
define i32 @get_int(i32 %a, i32 %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%x = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
store i32 %b, i32* %b.addr, align 4
%0 = load i32* %a.addr, align 4
%1 = load i32* %b.addr, align 4
*%call = call i32 @sum_mockup(i32 %0, i32 %1)* *; Use the first
function generated*
store i32 %call, i32* %x, align 4
%2 = load i32* %x, align 4
%call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
([20 x i8]* @.str, i32 0, i32 0), i32 %2)
%3 = load i32* %x, align 4
ret i32 %3
}
The result was: 10
; sum always remains a declaration
declare i32 @sum(i32, i32) #1
*define i32 @sum_mockup(i32, i32)* *#1 {**
**mockup_block:**
** ret i32 10**
**}*
****************************
*[C Code] getPointerToFunction()= 10****// Pointer to*
*@sum_mockup(i32, i32)*
****************************
; Function Attrs: nounwind uwtable
define i32 @get_int(i32 %a, i32 %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%x = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
store i32 %b, i32* %b.addr, align 4
%0 = load i32* %a.addr, align 4
%1 = load i32* %b.addr, align 4
*%call = call i32 @sum(i32 %0, i32 %1)* *// Change it back to the
declaration*
store i32 %call, i32* %x, align 4
%2 = load i32* %x, align 4
%call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
([20 x i8]* @.str, i32 0, i32 0), i32 %2)
%3 = load i32* %x, align 4
ret i32 %3
}
; Function Attrs: nounwind uwtable
define i32 @get_int(i32 %a, i32 %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%x = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
store i32 %b, i32* %b.addr, align 4
%0 = load i32* %a.addr, align 4
%1 = load i32* %b.addr, align 4
*%call = call i32 @sum_mockup_1(i32 %0, i32 %1) ; Use the other
function generated*
store i32 %call, i32* %x, align 4
%2 = load i32* %x, align 4
%call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
([20 x i8]* @.str, i32 0, i32 0), i32 %2)
%3 = load i32* %x, align 4
ret i32 %3
}
The result was: 10
declare i32 @sum(i32, i32) #1
*define i32 @sum_mockup_1(i32, i32) #1 {**
**mockup_block:**
** ret i32 5**
**}*
****************************
*[C Code] getPointerToFunction()= 5* *// Pointer to*
*@sum_mockup_1(i32, i32)*
****************************
; Function Attrs: nounwind uwtable
define i32 @get_int(i32 %a, i32 %b) #0 {
entry:
%a.addr = alloca i32, align 4
%b.addr = alloca i32, align 4
%x = alloca i32, align 4
store i32 %a, i32* %a.addr, align 4
store i32 %b, i32* %b.addr, align 4
%0 = load i32* %a.addr, align 4
%1 = load i32* %b.addr, align 4
*%call = call i32 @sum(i32 %0, i32 %1)* *// Change it back to the
declaration*
store i32 %call, i32* %x, align 4
%2 = load i32* %x, align 4
%call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
([20 x i8]* @.str, i32 0, i32 0), i32 %2)
%3 = load i32* %x, align 4
ret i32 %3
}
If I get a pointer to the function 'get_int()' I still have the same
problem of getting the same return value of the first generated
function. But when I get a pointer to the generated functions themselves
'sum_mockup_*()' I get the actual value I'm expecting.
On 28/06/14 22:48, Yaron Keren wrote:> getFunction() -> getPointerToFunction()
>
>
>
>
> 2014-06-29 6:40 GMT+03:00 Yaron Keren <yaron.keren at gmail.com
> <mailto:yaron.keren at gmail.com>>:
>
> Hi Adrian,
>
> freeMachineCodeForFunction is required but
> recompileAndLinkFunction is not,
> you can use getFunction() always.
>
> Try to M->dump() calling M->getFunction() where M is the Module
*.
> See if how the changes appear in the module dump as expected.
>
> Yaron
>
>
>
>
>
> 2014-06-29 5:56 GMT+03:00 Adrian Ortega <elfus0.1 at gmail.com
> <mailto:elfus0.1 at gmail.com>>:
>
> Hello,
>
> The problem I'm having is that I modify a function body by
> using 'Value::replaceAllUsesWith' and then execute it with
the
> JIT engine several times but I always get the output from the
> first iteration for all the iterations.
>
> This is what I do:
>
>
> I generate the following 2 functions on the fly based on the
> FunctionType of the declaration below in C code.
>
> define i32 @get_int_5(i32, i32) #1 {
> ret i32 5
> }
>
> define i32 @get_int_10(i32, i32) #1 {
> ret i32 10
> }
>
> I have the following C code:
>
>
> // This is only a declaration
> // I use this FunctionType to generate the functions above
> int sum(int a, int b);
>
> int get_int()
> {
> return sum(a,b);
> }
>
> I replace the call to 'sum()' by calling
> Value::replaceAllUsesWith for one of the functions generated
> above, run with JIT. I checked the code generated and it
> actually changes the call from 'sum()' to
'get_int_5()' and I
> get a 5 as return value when I call the function with the JIT
> execution engine.
>
> Then I repeat the previous step using
> 'Value::replaceAllUsesWith' for the next function I
generated
> and run it with JIT. Then again the code generated is what I
> expected, this time
> function call changes from 'sum()' to
'get_int_10()', however
> the problem is I get a 5 instead of a 10.
>
> I tried 'recompileAndLinkFunction' as well as
> 'freeMachineCodeForFunction' and I always get the return
value
> from the first function, and not the second as I should even
> though the generated code that I dump() says that it has the
> correct function call.
>
> I am using version 3.4 for both clang and llvm. And also I'm
> using the JIT Engine and not the MCJIT.
>
> Do you have have any idea why the references or 'uses'
changes
> are not reflected in the code JIT'ed ?
>
> Regards.
>
>
>
>
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
> http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20140629/3d16165f/attachment.html>
Adrian Ortega
2014-Jun-29 14:53 UTC
[LLVMdev] Wrong behavior modifying and executing llvm::Function with JIT Engine
Another thing I just tried was to give 'sum()' the following
implementation:
int sum(int a, int b) { return 99; }
Now what I did was:
1. Call 'get_int()' which will call 'sum(){return 99;}'
2. Change the call instruction to 'sum_mockup', I dumped the code
and the change is done, but when calling 'get_int()' it calls
'sum(){return 99;}'
I know it might be too rushed to say what the problem is, but it seems
that when a function has been compiled and executed in the JIT engine,
it will remain linked to other functions no matter what regardless of
changing the call instruction.
On 29/06/14 09:00, Adrian Ortega wrote:> I tried using 'getPointerToFunction()' and the correct function I
> generated was called from C code, but when it runs inside the JIT
> engine it always returns the value of the first function. I even tried
> to 'deleteBody()' and 'removeFromParent()' from the first
function
> generated, and still returns the first value.
>
> I also tried using 'dump()' to see if the values where being
updated.
> This is the C code I run with the JIT engine:
>
> #include <stdio.h>
>
> int sum(int a, int b); // declaration
>
> int get_int(int a, int b)
> {
> int x = sum(a,b);
> printf("The result was: %d\n",x);
> return x;
> }
>
> As you can see I print the return value of the function. The functions
> I generate and that I called 'get_int_*()' in the previous email
are
> now called 'sum_mockup_N()'. This is the code LLVM IR code:
>
> ; Function Attrs: nounwind uwtable
> define i32 @get_int(i32 %a, i32 %b) #0 {
> entry:
> %a.addr = alloca i32, align 4
> %b.addr = alloca i32, align 4
> %x = alloca i32, align 4
> store i32 %a, i32* %a.addr, align 4
> store i32 %b, i32* %b.addr, align 4
> %0 = load i32* %a.addr, align 4
> %1 = load i32* %b.addr, align 4
> *%call = call i32 @sum_mockup(i32 %0, i32 %1)* *; Use the first
> function generated*
> store i32 %call, i32* %x, align 4
> %2 = load i32* %x, align 4
> %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
> ([20 x i8]* @.str, i32 0, i32 0), i32 %2)
> %3 = load i32* %x, align 4
> ret i32 %3
> }
>
> The result was: 10
>
> ; sum always remains a declaration
> declare i32 @sum(i32, i32) #1
>
> *define i32 @sum_mockup(i32, i32)* *#1 {**
> **mockup_block:**
> **ret i32 10**
> **}*
>
> ****************************
> *[C Code] getPointerToFunction()= 10****// Pointer to*
> *@sum_mockup(i32, i32)*
> ****************************
>
> ; Function Attrs: nounwind uwtable
> define i32 @get_int(i32 %a, i32 %b) #0 {
> entry:
> %a.addr = alloca i32, align 4
> %b.addr = alloca i32, align 4
> %x = alloca i32, align 4
> store i32 %a, i32* %a.addr, align 4
> store i32 %b, i32* %b.addr, align 4
> %0 = load i32* %a.addr, align 4
> %1 = load i32* %b.addr, align 4
> *%call = call i32 @sum(i32 %0, i32 %1)* *// Change it back to the
> declaration*
> store i32 %call, i32* %x, align 4
> %2 = load i32* %x, align 4
> %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
> ([20 x i8]* @.str, i32 0, i32 0), i32 %2)
> %3 = load i32* %x, align 4
> ret i32 %3
> }
>
>
> ; Function Attrs: nounwind uwtable
> define i32 @get_int(i32 %a, i32 %b) #0 {
> entry:
> %a.addr = alloca i32, align 4
> %b.addr = alloca i32, align 4
> %x = alloca i32, align 4
> store i32 %a, i32* %a.addr, align 4
> store i32 %b, i32* %b.addr, align 4
> %0 = load i32* %a.addr, align 4
> %1 = load i32* %b.addr, align 4
> *%call = call i32 @sum_mockup_1(i32 %0, i32 %1) ; Use the other
> function generated*
> store i32 %call, i32* %x, align 4
> %2 = load i32* %x, align 4
> %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
> ([20 x i8]* @.str, i32 0, i32 0), i32 %2)
> %3 = load i32* %x, align 4
> ret i32 %3
> }
>
> The result was: 10
>
> declare i32 @sum(i32, i32) #1
>
>
> *define i32 @sum_mockup_1(i32, i32) #1 {**
> **mockup_block:**
> **ret i32 5**
> **}*
>
> ****************************
> *[C Code] getPointerToFunction()= 5* *// Pointer to*
> *@sum_mockup_1(i32, i32)*
> ****************************
>
> ; Function Attrs: nounwind uwtable
> define i32 @get_int(i32 %a, i32 %b) #0 {
> entry:
> %a.addr = alloca i32, align 4
> %b.addr = alloca i32, align 4
> %x = alloca i32, align 4
> store i32 %a, i32* %a.addr, align 4
> store i32 %b, i32* %b.addr, align 4
> %0 = load i32* %a.addr, align 4
> %1 = load i32* %b.addr, align 4
> *%call = call i32 @sum(i32 %0, i32 %1)* *// Change it back to the
> declaration*
> store i32 %call, i32* %x, align 4
> %2 = load i32* %x, align 4
> %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
> ([20 x i8]* @.str, i32 0, i32 0), i32 %2)
> %3 = load i32* %x, align 4
> ret i32 %3
> }
>
>
> If I get a pointer to the function 'get_int()' I still have the
same
> problem of getting the same return value of the first generated
> function. But when I get a pointer to the generated functions
> themselves 'sum_mockup_*()' I get the actual value I'm
expecting.
>
>
>
> On 28/06/14 22:48, Yaron Keren wrote:
>> getFunction() -> getPointerToFunction()
>>
>>
>>
>>
>> 2014-06-29 6:40 GMT+03:00 Yaron Keren <yaron.keren at gmail.com
>> <mailto:yaron.keren at gmail.com>>:
>>
>> Hi Adrian,
>>
>> freeMachineCodeForFunction is required but
>> recompileAndLinkFunction is not,
>> you can use getFunction() always.
>>
>> Try to M->dump() calling M->getFunction() where M is the
Module *.
>> See if how the changes appear in the module dump as expected.
>>
>> Yaron
>>
>>
>>
>>
>>
>> 2014-06-29 5:56 GMT+03:00 Adrian Ortega <elfus0.1 at gmail.com
>> <mailto:elfus0.1 at gmail.com>>:
>>
>> Hello,
>>
>> The problem I'm having is that I modify a function body by
>> using 'Value::replaceAllUsesWith' and then execute it
with
>> the JIT engine several times but I always get the output from
>> the first iteration for all the iterations.
>>
>> This is what I do:
>>
>>
>> I generate the following 2 functions on the fly based on the
>> FunctionType of the declaration below in C code.
>>
>> define i32 @get_int_5(i32, i32) #1 {
>> ret i32 5
>> }
>>
>> define i32 @get_int_10(i32, i32) #1 {
>> ret i32 10
>> }
>>
>> I have the following C code:
>>
>>
>> // This is only a declaration
>> // I use this FunctionType to generate the functions above
>> int sum(int a, int b);
>>
>> int get_int()
>> {
>> return sum(a,b);
>> }
>>
>> I replace the call to 'sum()' by calling
>> Value::replaceAllUsesWith for one of the functions generated
>> above, run with JIT. I checked the code generated and it
>> actually changes the call from 'sum()' to
'get_int_5()' and I
>> get a 5 as return value when I call the function with the JIT
>> execution engine.
>>
>> Then I repeat the previous step using
>> 'Value::replaceAllUsesWith' for the next function I
generated
>> and run it with JIT. Then again the code generated is what I
>> expected, this time
>> function call changes from 'sum()' to
'get_int_10()', however
>> the problem is I get a 5 instead of a 10.
>>
>> I tried 'recompileAndLinkFunction' as well as
>> 'freeMachineCodeForFunction' and I always get the
return
>> value from the first function, and not the second as I should
>> even though the generated code that I dump() says that it has
>> the correct function call.
>>
>> I am using version 3.4 for both clang and llvm. And also
I'm
>> using the JIT Engine and not the MCJIT.
>>
>> Do you have have any idea why the references or 'uses'
>> changes are not reflected in the code JIT'ed ?
>>
>> Regards.
>>
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>> http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20140629/9632dadf/attachment.html>