-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
switching to MCJIT #3922
Comments
Is a debugger one of those important reasons? |
That's rather surprising given Apple's investment in LLVM. You sure about that? |
MCJIT is important for debugger support and for generating binaries. |
I didn't say any of the reasons are important. @StefanKarpinski Those statements aren't entirely accurate. With the help of ihnorton, I was able to dump the JIT code to a file and compile it offline, resulting in a Julia binary, with the improved debugger support that entails. The MCJIT may be able to provide the same information directly to gdb for JIT code, but that's still unclear to me. The main reason to switch may be that the LLVM group don't appear to be working on the current JIT, but are intending to finish the MCJIT as a simple replacement. I'm a bit confused by the lack of support on Darwin as well. I opened this issue partly as documentation of the current state, and partly in the hope that someone would be able to identify the problem. |
Following this post on the LLVM blog I added |
Ah, excellent! That post explains a lot about what we will need to fix. |
Andrew Kaylor (andrew.kaylor at intel.com) was at the LLVM Developers Meeting last week in San Francisco and later sent me the following information, which seems worth recording here: "The exception handling support for the old JIT engine is being removed in the LLVM 3.4 release and I expect the old JIT engine itself to be deprecated in LLVM 3.5 and dropped entirely in 3.6. I spent some time with Keno Fischer (@loladiro) trying to get Julia to work with MCJIT instead, which does have exception handling support now. We ran into a couple of problems related to the way Julia was using the old JIT. With the old JIT, you could put everything into a single llvm::Module instance and continue adding new functions and variables to the module even after you have generated code from previously defined functions. With MCJIT, you can’t modify an llvm::Module after you have generated code from it. We modified the Julia source to create a new module as needed. This was kind of hacked in and not in the proper place, but we were just trying to get something up and running. Once multiple modules were being created, we ran into a problem that the Julia code was generating calls to functions that were defined in other modules without creating prototypes for them, which caused LLVM’s module verifier to reject the module. A similar problem existed with variables. We put in some more, even uglier hacks, to get around the external function and variable problem. That got far enough to generate a Julia system image, but it was breaking somewhere in the smoke tests. That’s where we left things at the end of the Dev Meeting. I exchanged a couple of e-mails with Keno since then about a problem that was uncovered by the LLVM address sanitizer tool (I’ve since fixed that issue in LLVM trunk), but I don’t know if he has figured out the problem that was preventing Julia from working with MCJIT." |
To sum up my current state: |
Is one of the motivations behind MCJIT inlining? Will having each function in a separate module eliminate LLVM's ability to inline? |
We do our own language level inlining without LLVM in the picture at the moment anyway, so it doesn't affect us. I don't know if there's a cross-module inlining pass, though I imagine there would be and if not it wouldn't be too difficult to write one. Nevertheless, I'd love to figure out how to avoid the finalizer issue, thus putting more functions in a module (which can only be beneficial). I'm thinking, since it's actually pretty rare that this happens, just do the naive thing and create a separate module for the finalizer before compiling, fixing up any references (think |
@loladiro I believe putting every function in its own module is supposed to work, at least, that's what I got from this blog post. |
No, it is (I talked extensively with Andy who wrote that blog post last week), there's just a bit of trouble with assumptions we make in the current code base. |
I know currently we do our own inlining, but to me it seems attractive in principle to offload some of that onto a compiler. I imagine they've put quite a lot of effort into questions like "when is it better to inline, and when not?" IIUC, right now our inlining is pretty simple (e.g. until Jameson's work gets merged, any code with a conditional will not be inlined, which means not much gets inlined). So currently it's not an issue, but eventually we might want some of that wisdom that I imagine compiler-makers must have accumulated. |
I agree, I've actually talked to Jeff about enabling the inlining pass before. For now, it doesn't much matter either way though. |
@JeffBezanson Here's the backtrace from earlier. Contrary to my previous statement this is in type inference not gc. Still not sure why it tries to compile the unfinished module. |
I have a branch that works, but I already messed up earlier trying to disentangle it from everything else, so I'll wait for my various other pull requests to make it onto master and then create a branch off that. |
Eventually, we may need/want to switch to MCJIT for various reasons. This patch is all that appears to be needed (on Linux):
Unfortunately, it doesn't seem to run on Apple yet?
The text was updated successfully, but these errors were encountered: