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>