Output to a DLL

Hi all,

I’d like to be able to write JIT-compiled code to a Windows DLL. I have no idea where to start though. Does LLVM already offer some support for this? Or would it be straightforward to write my own DLL writer (no advanced features needed)? Or maybe I could use an external linker? All help highly appreciated!

Cheers,

Nicolas

"Nicolas Capens" <nicolas@capens.net> writes:

Hello Nicolas.

I'd like to be able to write JIT-compiled code to a Windows DLL. I have no
idea where to start though. Does LLVM already offer some support for
this?

Nope. Don't hold your breadth waiting for it. It is far from trivial to
do.

I don't know your requirements, but mine is to avoid compilation every
time the hosting application starts.

I was thinking on:

1. Compile and spit bitecode from the JIT the first time, load it on
subsequent sessions. Seems doable. Doesn't work if your goal is
using code on non-LLVM-aware applications, but if you want to do this
the JIT is of no use anyways.

2. Act as a traditional compiler and generate a shared library via
llvmc + assembler + linker. Tricky, even more so on Windows. Resolving
symbols is not as easy as is on case 1.

Or would it be straightforward to write my own DLL writer (no advanced
features needed)? Or maybe I could use an external linker? All help highly
appreciated!

If you end hacking a DLL writer, please contribute it to LLVM :slight_smile:

When you say “spit bitecode from the JIT the first time, load it on subsequent sessions” :

  • do you want to write the IR in a file via BitcodeWriter and re-read it via BitcodeReader ? (you will pay the cost of native code emission on each load ?)
  • do you want to write the native code ? In that case, how do you retrieve the size of the buffer prepared by the “getPointerToFunction” method ? Is it safe ? I was wondering on how memory access to global variable will come back in this case ?

Olivier.

Olivier Meurant <meurant.olivier@gmail.com> writes:

When you say "spit bitecode from the JIT the first time, load it on
subsequent sessions" :
- do you want to write the IR in a file via BitcodeWriter and re-read it via
BitcodeReader ? (you will pay the cost of native code emission on each load
?)

Yes. It is a small cost compared with compiling all the way from the
source code.

- do you want to write the native code ? In that case, how do you retrieve
the size of the buffer prepared by the "getPointerToFunction" method ? Is it
safe ? I was wondering on how memory access to global variable will come
back in this case ?

I don't want to write and read native code because it is not relocatable.

I’d like to be able to write JIT-compiled code to a Windows DLL. I have no
idea where to start though. Does LLVM already offer some support for this?

You can't use the JIT to compile code for a DLL; it simply isn't
designed for that.

Or would it be straightforward to write my own DLL writer (no advanced
features needed)? Or maybe I could use an external linker? All help highly
appreciated!

You can write out an assembly (.s) file and use mingw as+ld to build a
DLL. Essentially, this is just building a DLL the same way a
conventional compiler like llvm-gcc would.

Directly emitting a DLL would be a lot of work, although it doesn't
require any architectural changes to LLVM; you'd need something like
http://wiki.llvm.org/Direct_Object_Code_Emission plus some code to
handle linking.

-Eli

Hi Óscar,

For me writing a DLL would have two purposes: one is to reduce compilation
time (i.e. make it work like a cache), but a second very important goal is
to be able to profile code at the assembly level (using AMD's CodeAnalyst
for example).

Fortunately, the code I'm generating consists of only pure functions. So
there's no need for linking symbols.

Anyway, thanks for the ideas. I'll definitely investigate generating
assembly output and using an external compiler and linker for it.

Cheers,

Nicolas

Hi Eli,

Thanks a lot for the advise. The existing direct object code emission looks
very interesting and I might give it a try to create a basic DLL writer.

Generating an assembly file and compiling it to a DLL 'externally' sounds
like the most straightforward way for now so I'll try that first...

Cheers,

Nicolas