This is sounding rather like getLazyBitcodeModule is simply incompatible with MCJIT. Can anybody confirm that this is definitely the case? Is it by design, or by omission, or bug? Re your option #1 and #2 -- sorry for the newbie questions, but can you point me to docs or code examples for how the linking or object caching should be achieved? If I do either of these rather than seeding my bitcode into the same module where I'm dynamically assembling my IR, does that mean that it will be unable to inline those functions? It's possible that my best option may be to give up on getLazyBitcodeModule when using MCJIT, reverting back to ParseBitcodeFile, but try to lower compilation overhead by carefully dividing my module into just the parts that get the most bang-for-buck with inlining (keep those in the bitcode, but much less to compile), and move the rest into my app and have it resolve the symbols but not be able to inline. -- lg On Jan 21, 2014, at 9:51 AM, Kaylor, Andrew <andrew.kaylor at intel.com> wrote:> Hi Larry, > > I'm pretty sure MCJIT won't do what you need without some changes to the way you're doing things. > > When MCJIT compiles a Module, it compiles the entire Module and tries to resolve any and all undefined symbols. I'm not familiar with getLazyBitcodeModule, but at a glance (and cross referencing your comments below) it seems that it tries to add GlobalValues to a Module as they are needed. MCJIT doesn't let you modify Modules once it has compiled them, so that's not going to work. Even if we built some scheme into MCJIT to materialize things before it compiled a Module it would end up materializing everything, so that wouldn't help you. > > You have a few options. > > 1. You can continue to load the pre-existing bitcode with getLazyBitcodeModule then emit your dynamic code into a separate Module which gets linked against the "lazy" Module before it is handed off to MCJIT. > > 2. You can use MCJIT's object caching mechanism to load a fully pre-compiled version of your bitcode. Again you'd need to have your dynamic code in a separate Module, but in this case MCJIT would take care of the linking. If you know the target architecture ahead of time you can install the cached object with your application. If not, you'd need to take the large compilation hit once. After that it should be fairly fast. The downside is that you'd potentially have a lot more code loaded into memory than you needed. > > 3. You can break the pre-compiled code into smaller chunks and compile them into an archive file. MCJIT recently added the ability to link against archive files. This would give you control over the granularity at which pieces of your pre-compiled code get loaded while also giving you the speed of the cached object file solution. The trade-off is that for this solution you do need to know the target architecture ahead of time. > > Hope this helps. > > -Andy >-- Larry Gritz lg at larrygritz.com
I would say that the incompatibility is by design. Not that anyone specifically wanted the incompatibility, but rather it's a known artifact of the MCJIT design. You can find an example of MCJIT's object caching here: http://blog.llvm.org/2013/08/object-caching-with-kaleidoscope.html The two blog entries before that may also be of use to you: http://blog.llvm.org/2013_07_01_archive.html I don't where you can find an example of the Module linking I described, but I think llvm::Linker is the class to look at. -Andy -----Original Message----- From: Larry Gritz [mailto:lg at larrygritz.com] Sent: Tuesday, January 21, 2014 10:52 AM To: Kaylor, Andrew Cc: LLVM Developers Mailing List Subject: Re: [LLVMdev] MCJIT versus getLazyBitcodeModule? This is sounding rather like getLazyBitcodeModule is simply incompatible with MCJIT. Can anybody confirm that this is definitely the case? Is it by design, or by omission, or bug? Re your option #1 and #2 -- sorry for the newbie questions, but can you point me to docs or code examples for how the linking or object caching should be achieved? If I do either of these rather than seeding my bitcode into the same module where I'm dynamically assembling my IR, does that mean that it will be unable to inline those functions? It's possible that my best option may be to give up on getLazyBitcodeModule when using MCJIT, reverting back to ParseBitcodeFile, but try to lower compilation overhead by carefully dividing my module into just the parts that get the most bang-for-buck with inlining (keep those in the bitcode, but much less to compile), and move the rest into my app and have it resolve the symbols but not be able to inline. -- lg On Jan 21, 2014, at 9:51 AM, Kaylor, Andrew <andrew.kaylor at intel.com> wrote:> Hi Larry, > > I'm pretty sure MCJIT won't do what you need without some changes to the way you're doing things. > > When MCJIT compiles a Module, it compiles the entire Module and tries to resolve any and all undefined symbols. I'm not familiar with getLazyBitcodeModule, but at a glance (and cross referencing your comments below) it seems that it tries to add GlobalValues to a Module as they are needed. MCJIT doesn't let you modify Modules once it has compiled them, so that's not going to work. Even if we built some scheme into MCJIT to materialize things before it compiled a Module it would end up materializing everything, so that wouldn't help you. > > You have a few options. > > 1. You can continue to load the pre-existing bitcode with getLazyBitcodeModule then emit your dynamic code into a separate Module which gets linked against the "lazy" Module before it is handed off to MCJIT. > > 2. You can use MCJIT's object caching mechanism to load a fully pre-compiled version of your bitcode. Again you'd need to have your dynamic code in a separate Module, but in this case MCJIT would take care of the linking. If you know the target architecture ahead of time you can install the cached object with your application. If not, you'd need to take the large compilation hit once. After that it should be fairly fast. The downside is that you'd potentially have a lot more code loaded into memory than you needed. > > 3. You can break the pre-compiled code into smaller chunks and compile them into an archive file. MCJIT recently added the ability to link against archive files. This would give you control over the granularity at which pieces of your pre-compiled code get loaded while also giving you the speed of the cached object file solution. The trade-off is that for this solution you do need to know the target architecture ahead of time. > > Hope this helps. > > -Andy >-- Larry Gritz lg at larrygritz.com
Thanks for the pointers. Am I correct in assuming that putting the precompiled bitcode into a second module and linking (or using the object caches) would result in ordinary function calls, but would not be able to inline the functions? -- lg On Jan 21, 2014, at 11:55 AM, Kaylor, Andrew <andrew.kaylor at intel.com> wrote:> I would say that the incompatibility is by design. Not that anyone specifically wanted the incompatibility, but rather it's a known artifact of the MCJIT design. > > You can find an example of MCJIT's object caching here: http://blog.llvm.org/2013/08/object-caching-with-kaleidoscope.html > > The two blog entries before that may also be of use to you: http://blog.llvm.org/2013_07_01_archive.html > > I don't where you can find an example of the Module linking I described, but I think llvm::Linker is the class to look at. > > -Andy >-- Larry Gritz lg at larrygritz.com