Ahoy JIT Users

Hi,

I am starting to poke at the LLVM JIT, which seems to be in need of some TLC.

If you are a "sophisticated" JIT user and are using either internal
APIs (either by integrating with LLVM, or by other C++ tricks), or are
using obscure or poorly documented public APIs (e.g., why is
runJITOnFunction exposed?) please make me aware of it!

I reserve the right to break anything which doesn't have a unit test
in the tree. :slight_smile:

I will try very hard to not break anything which *does* have an
existing public interface.

Cheers,
- Daniel

Will this poking include converting the JIT to use the MC framework?

I've added an MC based asm parser, disassembler, and code emitter recently to the MBlaze backend and it would be nice to get JIT support automatically :slight_smile:

-- Wesley Peck

Will this poking include converting the JIT to use the MC framework?

That is the motivation for me poking at things, yes.

I've added an MC based asm parser, disassembler, and code emitter recently to the MBlaze backend and it would be nice to get JIT support automatically :slight_smile:

I agree, that would be an excellent proof of the benefits of the
unified architecture!

- Daniel

Hi Daniel,

I don't think I'm using any internal APIs (I'm using EngineBuilder and
ExecutionEngine, not the JIT class directly).
Just tell me when you're done with the MC changes, and I'll test if my
code still works with it.

Some APIs that I use that don't have a unit-test (but I think their
purpose is quite well documented);
- DisableSymbolSearching
- InstallLazyFunctionCreator
- llvm::JITEmitDebugInfo = false (In production code I don't need it,
   so I turn it off to avoid the memory leaks it causes)
- llvm::DwarfExceptionHandling = false (similarly I don't use/need exc
   handling, so I don't want to spend time and memory to build and emit
   it)

One shortcoming is that even with DisambleSymbolSearching the JIT fails
to be created if it cannot resolve symbols in itself, I usually comment
out that line but I should probably submit a patch that fixes it
properly.
I don't link the JIT with -ldl at all, because I don't allow any
external calls: they are either completely forbidden, or solved to
functions in my code (forwarding to appropriate libc func if needed),
thats why I use the Lazy function creator.
Are your MC patches going to change anything wrt. symbol searching?

Also I use getPointerToFunction as a mean of trying to avoid creating
stubs, (and of course getting pointer to JITed code), and I use
addGlobalMapping (but I see this has a unit-test too).

I do use llvm_start_multithreaded, however it looks like it doesn't
like if I create multiple JITs in parallel so I just use a mutex
around all my use of LLVM APIs for now (they are 99% of the time not
happening in parallel anyway so mutex is no big deal).
However if you want me to test whether your new MCized JIT is completely
thread safe, then I can turn off my mutex, run my unit-test and see
if I get any crashes (or helgrind warnings).

Also take care with relocations on PowerPC, if you exceed 5M then you
need to use a different instruction. The old JIT doesn't know how to
do that so just asserts: LLVM has a patch in codegen that tries the
generate the correct instruction in the first place (and a unit-test
that I think is currently turned off), however if MC will be able to do
proper relocations by substituting the correct instruction (even ifthat
changes code size) like a real linker that would probably be more
reliable.

Best regards,
--Edwin

Excellent! I recently started experimenting with MCStreamers in the
hopes of creating an MCJITStreamer and ultimately making an MC JIT
engine. If you already have a good idea of how to make it all work,
then I'll eagerly await the results and help any way I can.

Hi Daniel,

You can also run ExceptionDemo, after setting BUILD_EXAMPLES to 1
and rebuilding llvm. I use Release+Asserts/examples/ExceptionDemo 2 3 7 -1
as an ad-hoc sanity check. This demo can be sensitive to JIT changes
because it relies on the Dwarf exception behavior, as implemented in the JIT,
to be working correctly for Linux and OS X. Arguments 2 3 7 -1, I believe cover
all its use cases, and are somewhat explained in a no-arg run, and in the code.

Hope this helps

Garrison

Go for it! I'm expecting this will break the gdb interface and the
unwind tables, but hopefully that can be fixed later.

Reid

I'm also eager to try the new JIT with Pure
(http://pure-lang.googlecode.com/). :slight_smile:

Daniel Dunbar wrote:

If you are a "sophisticated" JIT user and are using either internal
APIs (either by integrating with LLVM, or by other C++ tricks), or are
using obscure or poorly documented public APIs (e.g., why is
runJITOnFunction exposed?) please make me aware of it!

I'm not aware of any dirty tricks or use of undocumented APIs, but Pure
uses the JIT quite heavily, since virtually every Pure script gets run
through the JIT when using the Pure interpreter. Moreover, Pure fully
employs the dynamic characteristics of the JIT (recompiling functions on
the fly when a new term rewriting rule gets added, for instance). Pure
has shaken out bugs in the JIT implementation before, so I guess it
could serve as a stress test for the new implementation. (Before that
can happen, I'll probably have to sync the Pure sources with latest TOT
again, but it works perfectly with the 2.8 release, so I hope that only
minor changes should be required, if any.)

Cheers,
Albert

[Resend: I don't know why Reply-to-all button comes after Repy one]

Hi,

I am starting to poke at the LLVM JIT, which seems to be in need of some TLC.

If you are a "sophisticated" JIT user and are using either internal
APIs (either by integrating with LLVM, or by other C++ tricks), or are
using obscure or poorly documented public APIs (e.g., why is
runJITOnFunction exposed?) please make me aware of it!

Rather than "sophisticated", does "completely insane" JIT user count :slight_smile: ?

For a while now on and off I've been trying to get a stochastic instruction
scheduling working (for just one function body). The idea is to generate a
reasonable number of correct schedules and time them in a feedback-directed way.
The idea is to just replace code at the scheduling level and piggy
back on lowering, the existing register
allocation, machine code emission, etc. What this wants is hence to be
able to "sit a controller" at the scheduling routine and repeatedly
generate a schedule,
do all the following steps and then run the code and feed the timing result
back to the controller.

The design of the LLVM JIT really doesn't expect anything other than
"single-input/single-output"
processing at any point in the JIT. Changing this properly would be
both a lot of work
and likely of no use to anyone else, so I've been trying to use the nasty
workaround of

* in the controller loop at the scheduler, after generating a candidate schedule
fork() and wait for the child copy, it wait()s.

* the child copy returns from the scheduler and runs the rest of the JIT and
then runs the code in a timing block, returning the time taken.

* the controller picks up this value and uses it to guide new schedule creation.

Amazingly, as far as I can tell if you build llvm with
--enable-threads=no this works.
(If you don't disable threads it looks like it gets stuck in locking
instructions even
thought there's no other threads around.)

I wouldn't remotely expect you to deliberately make sure this continues to work
(it's such a mad thing to do), but just wrote to let you know one thing that is
bieng attempted out-of-tree.

(In case anyone asks why try and do something that so rubs against
llvm's design, it's basically a trade-off. Writing a special code generation
program would make the scheduling easier, but would also require me to
figure out the best way to lower C constructions like "a[i++]" on from the
many possibiliteis on x86 and ARM. It looks like it's marginally less work
to do nasty things to the LLVM codebase than learn and code that up myself.)

Regards,
David Tweed

[Resend: I don't know why Reply-to-all button comes after Repy one]

Hi,

I am starting to poke at the LLVM JIT, which seems to be in need of some TLC.

If you are a "sophisticated" JIT user and are using either internal
APIs (either by integrating with LLVM, or by other C++ tricks), or are
using obscure or poorly documented public APIs (e.g., why is
runJITOnFunction exposed?) please make me aware of it!

Rather than "sophisticated", does "completely insane" JIT user count :slight_smile: ?

Nope, I don't think you count. :slight_smile:

I can only hope you are willing to update your code to track changes
on TOT if you are willing to be as invasively intertwined with LLVM!

- Daniel