NQP on LLVM: How to Port

I’ve since realized that writing a version of NQP on LLVM from scratch would be either quite a lot of work or, by taking as many of the .nqp files as I can from the exisiting NQP for a self-compiling compiler, essentialy the same as a porting of NQP. So, I’ve instead tried poking around in the NQP codebase to see where I’d be spending a lot of time doing such a port.

In NQP there are two directories where I’ll likely focus my attention first: ops/ and pmc/ . ops/ contains the opcode extensions for Parrot (IIUC), while pmc/ contains the custom Parrot PMCs for use in NQP. Both of these folders take advantage of a mechanism in Parrot that allows for a modification of the language of Parrot externally, without modifying Parrot itself or recompiling the entirety of it.

LLVM has no such mechanism. If I wanted to modify the language of LLVM like what ends up happening in Parrot, I’d not only have to modify the actual LLVM codebase, but instructions (opcodes) and types are two of the things that, when added, break LLVM’s bitcode format. Not good. To be fair, I could implement the instructions as intrinsics instead, but that still leaves types, and modifying LLVM from within still seems like a Bad Thing™.

My current theoretical solution is to replace the files in ops/ and pmc/ with hand-coded .ll offering up the same functionality. ops/ is easy enough, I can just implement those opcodes as regular ol’ LLVMIR functions. pmc/ is a bit trickier, because LLVMIR provides no classes or any such thing. But just because OOP isn’t built-in, doesn’t mean I can’t do OOP. I’d either use LLVMIR structures (with normal variables as “attributes” and pointers to functions as “methods”), or just create a mess of LLVMIR that in the end handles like objects, from the outside.

Questions I’ll certainly have to ask on the llvm-dev mailing list, for sure.

I have two last concerns with putting NQP on LLVM. The first is where the actual generation of PIR starts. I have yet to find the spot where PIR instructions are emitted, which makes me think that’s all handled in Parrot, with NQP just sending it a structure representing the NQP code it parsed. If this is the case, then that’d be interesting to port to LLVM. Since it’s best to let LLVM generate LLVMIR for me, I’d likely end up writing a C/++ “middleman” of sorts between the .nqp files of NQP and LLVM, where this C/++ middleman takes what NQP’s final output is and sends it through LLVM’s IR generators.

The final concern is where to begin coding so that it takes the least code before I can test the porting of NQP as it goes. I really wouldn’t feel good about doing the entire port without running tests frequently (or even once).

Questions I’ll certainly have to ask jnthn, for sure.

This sounds like a difficult, but fun, project. I hope it is.

About these ads
This entry was posted in Think Tank and tagged , , , , . Bookmark the permalink.

3 Responses to NQP on LLVM: How to Port

  1. Daniel Ruoso says:

    Hm… I just realized I posted my really-long-comment in the wrong post… Please note my comment in the previous post…

    • lueinc says:

      I read your comment, and it is helpful. I’ll be sure to refer back to it when I’m able to go into writing NQP on LLVM full swing, even though I don’t plan on generating C code to pass to LLVM (or more specifically, clang). Thank you as well for pointing me to which calling convention I should use in the LLVMIR. :)

  2. Ben Goldberg says:

    You might be interested in looking at:

    https://github.com/jnthn/nqp-jvm-prep

    Where Jonathan Worthington is doing preparatory work for giving NQP a second backend, so it will work on both parrot and the java virtual machine.

    He’s also cleaning up some things so that additional backends (such as LLVM) will be easier.

    It doesn’t [yet] pass all the tests, since not all operations have been implemented, and because of this, it cannot [yet] compile Rakudo, but he’s actively working on it, making regular updates.

    And while the Rakudo Perl6 compiler is a complicated program, needing every last bit of functionality that NQP provides, there are quite a few programs, written in the NQP language, that his port is capable of compiling into java bytecodes, and which can run correctly on the JVM.

    That includes (his version of) the NQP compiler itself. It’s fully bootstrapped, and capable of running on the jvm and compiling itself into java bytecodes.

    So, the fastest way to get an LLVM port would be to make a branch from his branch, and start hacking. The downside of course would be that if he chooses to modify anything other than java-specific stuff, you might need to adjust your own code to stay compatible.

    The other fast way would be to contribute to his branch of the code, so that he can merge it back into Rakudo’s main branch, and *then* make a branch on which to hack.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s