Hayden Livingston
2015-Mar-14 02:48 UTC
[LLVMdev] Thoughts about ExecutionEngine/MCJIT interface
Another question: Lang, when do you think it'll be ok to move it to the C Bindings? On Fri, Mar 13, 2015 at 6:39 PM, Lang Hames <lhames at gmail.com> wrote:> Hi Pawel, > > I agree. ExecutionEngine, in its current form, is unhelpful. I'd be in > favor of cutting the common interface back to something like: > > class ExecutionEngine { > public: > virtual void addModule(std::unique_ptr<Module> M) = 0; > virtual void* getGlobalValueAddress(const GlobalValue *GV) = 0; > virtual GenericValue runFunction(const Function *F, > const std::vector<GenericValue> &Args) > = 0; > }; > > That's the obvious common functionality that both the interpreter and > MCJIT provide. Beyond that I think things get pretty implementation > specific. > > For what it's worth, this is an issue that I'm trying to address with the > new Orc JIT APIs. Those expose the internals directly to give you more > control. If you don't want to be able to switch the underlying > execution-engine, they may be a good fit for your use-case. > > Cheers, > Lang. > > > On Sat, Mar 14, 2015 at 4:57 AM, Paweł Bylica <chfast at gmail.com> wrote: > >> Hi, >> >> I think ExecutionEngine as a common interface for both Interpreter and >> MCJIT is almost useless in the current form. There are separated methods in >> ExecutionEngine for similar or the same features provided by Interpreter >> and MCJIT, i.e. to get a pointer to function you should call >> getPointerToFunction() for Interpreter or getFunctionAddress() for MCJIT. >> >> Personally, I'm using MCJIT and wish to have access to some methods not >> available from ExecutionEngine. E.g. I would like to use getSymbolAddress() >> instead of getFunctionAddress() sometimes as getFunctionAddress() do some >> additional work what I'm sure has be done already. >> >> Maybe it's time face the truth that Interpreter and MCJIT based solutions >> are not so similar and different interfaces are needed. Or maybe some >> unification is possible? >> >> My propositions / discussion starting points: >> >> 1. Expose MCJIT header in public API. It will allow users to cast >> ExecutionEngine instance to MCJIT instance. >> 2. Separate Interpreter and MCJIT interfaces and add them to API. >> ExecutionEngine can still be a base class for real common part (like module >> list). >> 3. Try to alter ExecutionEngine interface to unify common Interpreter >> and MCJIT features. Is it possible to have one getFunction() method? >> >> - Paweł >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> > > _______________________________________________ > 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/20150313/7afa35ff/attachment.html>
Hi Hayden, Which aspect are you interested in seeing C bindings for? ExecutionEngine already has C bindings. We'd need buy-in from clients before before we considered any change that would affect the C-API, including restricting the interface, and we'd have to provide a transition plan to avoid rev-lock. That's probably doable though: I don't think anyone's particularly enamored of the current interface. We could consider exposing MCJIT functionality via the C-API, but we'd have to carefully pin down how the aspects we expose are expected to behave. The Orc APIs are tricker. There's two ways we could go: (1) Try to expose the full modular JIT components concept. In this case we'd have to add a type-erasing layer (AbstractJITLayer?) that uses virtual methods to call base layers. Then we could have C API for constructing and connecting the layers. This would give C users the closest possible experience to C++ users (with a little runtime overhead for the virtual calls). On the other hand it would be more work, and we'd want to be careful about how and when we expose the layers, since they're still so new. (2) Pick some canonical stack* and just expose that. This would be less work, and wouldn't risk constraining the layer implementations at all (provided you could still configure them somehow to provide the canonical stack functionality). On the other hand it'd mean C users wouldn't get the same experience from the APIs as C++ users. * If we're only going to expose one stack, it should probably be the The Lot (at least as it stands at the moment): 4) CompileOnDemandLayer. 3) LazyEmittingLayer. 2) IRCompilingLayer. 1) ObjectLinkingLayer. Cheers, Lang. On Sat, Mar 14, 2015 at 1:48 PM, Hayden Livingston <halivingston at gmail.com> wrote:> Another question: Lang, when do you think it'll be ok to move it to the C > Bindings? > > On Fri, Mar 13, 2015 at 6:39 PM, Lang Hames <lhames at gmail.com> wrote: > >> Hi Pawel, >> >> I agree. ExecutionEngine, in its current form, is unhelpful. I'd be in >> favor of cutting the common interface back to something like: >> >> class ExecutionEngine { >> public: >> virtual void addModule(std::unique_ptr<Module> M) = 0; >> virtual void* getGlobalValueAddress(const GlobalValue *GV) = 0; >> virtual GenericValue runFunction(const Function *F, >> const std::vector<GenericValue> &Args) >> = 0; >> }; >> >> That's the obvious common functionality that both the interpreter and >> MCJIT provide. Beyond that I think things get pretty implementation >> specific. >> >> For what it's worth, this is an issue that I'm trying to address with the >> new Orc JIT APIs. Those expose the internals directly to give you more >> control. If you don't want to be able to switch the underlying >> execution-engine, they may be a good fit for your use-case. >> >> Cheers, >> Lang. >> >> >> On Sat, Mar 14, 2015 at 4:57 AM, Paweł Bylica <chfast at gmail.com> wrote: >> >>> Hi, >>> >>> I think ExecutionEngine as a common interface for both Interpreter and >>> MCJIT is almost useless in the current form. There are separated methods in >>> ExecutionEngine for similar or the same features provided by Interpreter >>> and MCJIT, i.e. to get a pointer to function you should call >>> getPointerToFunction() for Interpreter or getFunctionAddress() for MCJIT. >>> >>> Personally, I'm using MCJIT and wish to have access to some methods not >>> available from ExecutionEngine. E.g. I would like to use getSymbolAddress() >>> instead of getFunctionAddress() sometimes as getFunctionAddress() do some >>> additional work what I'm sure has be done already. >>> >>> Maybe it's time face the truth that Interpreter and MCJIT based >>> solutions are not so similar and different interfaces are needed. Or maybe >>> some unification is possible? >>> >>> My propositions / discussion starting points: >>> >>> 1. Expose MCJIT header in public API. It will allow users to cast >>> ExecutionEngine instance to MCJIT instance. >>> 2. Separate Interpreter and MCJIT interfaces and add them to API. >>> ExecutionEngine can still be a base class for real common part (like module >>> list). >>> 3. Try to alter ExecutionEngine interface to unify common >>> Interpreter and MCJIT features. Is it possible to have one getFunction() >>> method? >>> >>> - Paweł >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> >>> >> >> _______________________________________________ >> 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/20150314/73083a47/attachment.html>
Hayden Livingston
2015-Mar-14 03:22 UTC
[LLVMdev] Thoughts about ExecutionEngine/MCJIT interface
I was referring to the ORC API. MCJIT is already exposed via C bindings. Your (2) sounds the easiest to me, and also seems to be more in line with the current C bindings approach (which I might add are superior to work with than the C++ API), and how I would expect an on-request JIT API to be used, So I put my vote for #2. On Fri, Mar 13, 2015 at 8:16 PM, Lang Hames <lhames at gmail.com> wrote:> Hi Hayden, > > Which aspect are you interested in seeing C bindings for? > > ExecutionEngine already has C bindings. We'd need buy-in from clients > before before we considered any change that would affect the C-API, > including restricting the interface, and we'd have to provide a transition > plan to avoid rev-lock. That's probably doable though: I don't think > anyone's particularly enamored of the current interface. > > We could consider exposing MCJIT functionality via the C-API, but we'd > have to carefully pin down how the aspects we expose are expected to behave. > > The Orc APIs are tricker. There's two ways we could go: > > (1) Try to expose the full modular JIT components concept. In this case > we'd have to add a type-erasing layer (AbstractJITLayer?) that uses virtual > methods to call base layers. Then we could have C API for constructing and > connecting the layers. This would give C users the closest possible > experience to C++ users (with a little runtime overhead for the virtual > calls). On the other hand it would be more work, and we'd want to be > careful about how and when we expose the layers, since they're still so new. > > (2) Pick some canonical stack* and just expose that. This would be less > work, and wouldn't risk constraining the layer implementations at all > (provided you could still configure them somehow to provide the canonical > stack functionality). On the other hand it'd mean C users wouldn't get the > same experience from the APIs as C++ users. > > * If we're only going to expose one stack, it should probably be the The > Lot (at least as it stands at the moment): > 4) CompileOnDemandLayer. > 3) LazyEmittingLayer. > 2) IRCompilingLayer. > 1) ObjectLinkingLayer. > > Cheers, > Lang. > > > On Sat, Mar 14, 2015 at 1:48 PM, Hayden Livingston <halivingston at gmail.com > > wrote: > >> Another question: Lang, when do you think it'll be ok to move it to the C >> Bindings? >> >> On Fri, Mar 13, 2015 at 6:39 PM, Lang Hames <lhames at gmail.com> wrote: >> >>> Hi Pawel, >>> >>> I agree. ExecutionEngine, in its current form, is unhelpful. I'd be in >>> favor of cutting the common interface back to something like: >>> >>> class ExecutionEngine { >>> public: >>> virtual void addModule(std::unique_ptr<Module> M) = 0; >>> virtual void* getGlobalValueAddress(const GlobalValue *GV) = 0; >>> virtual GenericValue runFunction(const Function *F, >>> const std::vector<GenericValue> >>> &Args) = 0; >>> }; >>> >>> That's the obvious common functionality that both the interpreter and >>> MCJIT provide. Beyond that I think things get pretty implementation >>> specific. >>> >>> For what it's worth, this is an issue that I'm trying to address with >>> the new Orc JIT APIs. Those expose the internals directly to give you more >>> control. If you don't want to be able to switch the underlying >>> execution-engine, they may be a good fit for your use-case. >>> >>> Cheers, >>> Lang. >>> >>> >>> On Sat, Mar 14, 2015 at 4:57 AM, Paweł Bylica <chfast at gmail.com> wrote: >>> >>>> Hi, >>>> >>>> I think ExecutionEngine as a common interface for both Interpreter and >>>> MCJIT is almost useless in the current form. There are separated methods in >>>> ExecutionEngine for similar or the same features provided by Interpreter >>>> and MCJIT, i.e. to get a pointer to function you should call >>>> getPointerToFunction() for Interpreter or getFunctionAddress() for MCJIT. >>>> >>>> Personally, I'm using MCJIT and wish to have access to some methods not >>>> available from ExecutionEngine. E.g. I would like to use getSymbolAddress() >>>> instead of getFunctionAddress() sometimes as getFunctionAddress() do some >>>> additional work what I'm sure has be done already. >>>> >>>> Maybe it's time face the truth that Interpreter and MCJIT based >>>> solutions are not so similar and different interfaces are needed. Or maybe >>>> some unification is possible? >>>> >>>> My propositions / discussion starting points: >>>> >>>> 1. Expose MCJIT header in public API. It will allow users to cast >>>> ExecutionEngine instance to MCJIT instance. >>>> 2. Separate Interpreter and MCJIT interfaces and add them to API. >>>> ExecutionEngine can still be a base class for real common part (like module >>>> list). >>>> 3. Try to alter ExecutionEngine interface to unify common >>>> Interpreter and MCJIT features. Is it possible to have one getFunction() >>>> method? >>>> >>>> - Paweł >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>>> >>>> >>> >>> _______________________________________________ >>> 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/20150313/3e2434d8/attachment.html>