Hi everyone, I would like to implement an equivalent mechanism of function callbacks in the JIT, but for fields. Typically in Java, when you compile a method, there may be some instructions (getfield, putfield) that depend on a type which is not yet resolved. I think the best way to do this in LLVM is to add an intrinsic. The intrinsic would be only valid if we jit, and would be lowered only in the codegen part (don't know yet if it would be in the target dependent or target independent part). The callback method will resolve the type and patch the store/load instruction so that the correct address is used (exactly like the JIT function callback compiles a method and patch the call) Now there is one issue to deal with here: how to represent the intrinsic? It can either be 1) llvm.getfieldptr.{type} or 2) have two kinds of intrinsics llvm.getfield.{type} and llvm.storefield.{type}. I'd prefer using 1) since its closer to the LLVM instruction set (GetElementPtrInst), however there may be some tricky issues on where and how the callback function must patch the code. For example, how are move instructions (for spilling registers) inserted in LLVM? By choosing 1), can I face the issue of having a move instruction between the getfieldptr call and the load/store? I probably can also face the problem of code optimization, where the store/load would not be next to the callback call. Will I also have these issues with 2)? I don't know if LLVM does optimization on DAG nodes. The dag nodes that I would like to generate for a llvm.loadfield.{type} would be: DAG.getCall(FieldCallback); // Or something similar, I don't know exactly the syntax ;-) DAG.getLoad(); When (if possible) can I be sure that these two instructions are next to each other in the native code? (Oh, and also, I would like codegen to not clobber caller-saved registers when doing the call. Is that even possible? This is just an optimization problem, so we can skip it for now). Thanks, Nicolas
On Nov 5, 2007, at 8:27 PM, Nicolas Geoffray wrote:> I would like to implement an equivalent mechanism of function > callbacks > in the JIT, but for fields. Typically in Java, when you compile a > method, there may be some instructions (getfield, putfield) that > depend > on a type which is not yet resolved. > > I think the best way to do this in LLVM is to add an intrinsic. The > intrinsic would be only valid if we jit, and would be lowered only in > the codegen part (don't know yet if it would be in the target > dependent > or target independent part).> > Now there is one issue to deal with here: how to represent the > intrinsic? It can either be 1) llvm.getfieldptr.{type} or 2) have two > kinds of intrinsics llvm.getfield.{type} and llvm.storefield.{type}.I don't think this is really the right way to go. Can you give an example snippet of Java code that would need this and what you are proposing? With a concrete example that shows how the lazy class loading stuff works we can talk about different possibilities, -Chris
Nicholas, I guess you're trying to solve the fragile base-class problem by deferring field offset calculations until JIT compilation time? Perhaps I'm missing something, but can't you accomplish this by using external constants in the source program, to be supplied at JIT/link time? external constant i32 @obj.x.offs; external constant i32 @obj.y.offs; define float @xPlusY(i8* %obj) { entry: %x.offs = load i32* @obj.x.offs; %x.ptr = getelementptr %obj, i32 %x.offs; %x.ptr2 = bitcast i8* %x.ptr to float* %x = load float* %x.ptr2 %y.offs = load i32* @obj.y.offs; %y.ptr = getelementptr %obj, i32 %y.offs; %y.ptr2 = bitcast i8* %y.ptr to float* %y = load float* %y.ptr2 %sum = add float %x, %y ret float %sum } Or, quite similarly, accessor functions also to be supplied by the JIT/ linker: declare float @obj.x(i8* %obj) declare float @obj.y(i8* %obj) define float @xPlusY(i8* %obj) { entry: %x = call float @obj.x(i8* %obj); %y = call float @obj.y(i8* %obj); %sum = add float %x, %y ret float %sum } In either case, an optimization pass could trivially zero out the overhead with no need to modify LLVM. On 2007-11-05, at 23:27, Nicolas Geoffray wrote:> Hi evaeryone, > > I would like to implement an equivalent mechanism of function > callbacks > in the JIT, but for fields. Typically in Java, when you compile a > method, there may be some instructions (getfield, putfield) that > depend > on a type which is not yet resolved. > > I think the best way to do this in LLVM is to add an intrinsic. The > intrinsic would be only valid if we jit, and would be lowered only in > the codegen part (don't know yet if it would be in the target > dependent > or target independent part). > > The callback method will resolve the type and patch the store/load > instruction so that the correct address is used (exactly like the JIT > function callback compiles a method and patch the call) > > Now there is one issue to deal with here: how to represent the > intrinsic? It can either be 1) llvm.getfieldptr.{type} or 2) have two > kinds of intrinsics llvm.getfield.{type} and llvm.storefield.{type}. > > I'd prefer using 1) since its closer to the LLVM instruction set > (GetElementPtrInst), however there may be some tricky issues on where > and how the callback function must patch the code. For example, how > are > move instructions (for spilling registers) inserted in LLVM? By > choosing > 1), can I face the issue of having a move instruction between the > getfieldptr call and the load/store? I probably can also face the > problem of code optimization, where the store/load would not be next > to > the callback call. > > Will I also have these issues with 2)? I don't know if LLVM does > optimization on DAG nodes. The dag nodes that I would like to generate > for a llvm.loadfield.{type} would be: > > DAG.getCall(FieldCallback); // Or something similar, I don't know > exactly the syntax ;-) > DAG.getLoad(); > > When (if possible) can I be sure that these two instructions are > next to > each other in the native code? > > (Oh, and also, I would like codegen to not clobber caller-saved > registers when doing the call. Is that even possible? This is just an > optimization problem, so we can skip it for now).— Gordon
Chris Lattner wrote:> > I don't think this is really the right way to go. Can you give an > example snippet of Java code that would need this and what you are > proposing? With a concrete example that shows how the lazy class > loading stuff works we can talk about different possibilities, > >Field operations in Java (getfield, putfield, getstatic, putstatic) do _not_ need what I'm proposing. What I'm proposing is just performance related (just like method patching in callbacks is an optimization in order to not call the callback everytime). Here's a simple example: consider class One: public class One { double a; } and class Two: public class Two { static double getDoubleFromOne(One arg) { return One.a; } } Here's the bytecode generated for the getDoubleFromOne method: ldarg 0 getfield "One", "a" return What happens in Java is that types are created lazily. Which means you can compile getDoubleFromOne without knowing the layout of the class One. Therefore, if you compile getDoubleFromOne without the layout information, the compiler will generate the code: r2 = arg0 r1 = getElementOffsetOf("One", "a"); return r1(r2); getElementOffsetOf will trigger resolution of the class "One" and return some offset for "a". My goal here is to avoid having the call to getElementOffsetOf for the next executions of getDoubleFromOne. One solution is to recompile getDoubleFromOne, now that we have the layout information, but this may not be desirable (increase of compilation time or what if we have many getElementOffsetOf calls in one method which belong to "if" statements, etc). What I would like to do is for getElementOffsetOf to dynamically patch the native code so that after the execution of getElementOffsetOf in the getDoubleFromOne method the native code looks like: r2 = arg0 nop return offset(r2) The problem is that getElementOffsetOf does not know where is the code for loading the field. The compiler may have move it after some instructions, or there may be some move instructions due to register spills, etc. Thus the introduction of the llvm.getfield* intrinsic :-)
Hi Gordon, Gordon Henriksen wrote:> Nicholas, > > I guess you're trying to solve the fragile base-class problem by > deferring field offset calculations until JIT compilation time? > >No. I'm deferring field offset calculation until /execution /time.> Perhaps I'm missing something, but can't you accomplish this by using > external constants in the source program, to be supplied at JIT/link > time? >If the JIT could make a callback to dynamically resolve the type, that's the idea (I'm thinking, if a field can have a GhostLinkage, can the compiler generate a callback? In this case I don't need a new intrinsic).> Or, quite similarly, accessor functions also to be supplied by the JIT/ > linker: >You lose performance here, because you have to call the accessor function each time you call the xPlusY function. My goal is to patch the native code so that you do not need to call these accessor functions again.> declare float @obj.x(i8* %obj) > declare float @obj.y(i8* %obj) > > define float @xPlusY(i8* %obj) { > entry: > %x = call float @obj.x(i8* %obj); > %y = call float @obj.y(i8* %obj); > %sum = add float %x, %y > ret float %sum > } > >After the first execution of xPlusY, the new native code (changed to LLVM, and imagine there are also some nops to remove the previsous accessors calls) of xPlusY would be: %x = offsetx(%obj) %y = offsety(%obj) %sum = add float %x, %y ret float %sum Thanks, Nicolas> In either case, an optimization pass could trivially zero out the > overhead with no need to modify LLVM. > > On 2007-11-05, at 23:27, Nicolas Geoffray wrote: > > >> Hi evaeryone, >> >> I would like to implement an equivalent mechanism of function >> callbacks >> in the JIT, but for fields. Typically in Java, when you compile a >> method, there may be some instructions (getfield, putfield) that >> depend >> on a type which is not yet resolved. >> >> I think the best way to do this in LLVM is to add an intrinsic. The >> intrinsic would be only valid if we jit, and would be lowered only in >> the codegen part (don't know yet if it would be in the target >> dependent >> or target independent part). >> >> The callback method will resolve the type and patch the store/load >> instruction so that the correct address is used (exactly like the JIT >> function callback compiles a method and patch the call) >> >> Now there is one issue to deal with here: how to represent the >> intrinsic? It can either be 1) llvm.getfieldptr.{type} or 2) have two >> kinds of intrinsics llvm.getfield.{type} and llvm.storefield.{type}. >> >> I'd prefer using 1) since its closer to the LLVM instruction set >> (GetElementPtrInst), however there may be some tricky issues on where >> and how the callback function must patch the code. For example, how >> are >> move instructions (for spilling registers) inserted in LLVM? By >> choosing >> 1), can I face the issue of having a move instruction between the >> getfieldptr call and the load/store? I probably can also face the >> problem of code optimization, where the store/load would not be next >> to >> the callback call. >> >> Will I also have these issues with 2)? I don't know if LLVM does >> optimization on DAG nodes. The dag nodes that I would like to generate >> for a llvm.loadfield.{type} would be: >> >> DAG.getCall(FieldCallback); // Or something similar, I don't know >> exactly the syntax ;-) >> DAG.getLoad(); >> >> When (if possible) can I be sure that these two instructions are >> next to >> each other in the native code? >> >> (Oh, and also, I would like codegen to not clobber caller-saved >> registers when doing the call. Is that even possible? This is just an >> optimization problem, so we can skip it for now). >> > > > — Gordon > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >