JIT compiler on ARM issue

Hello all,

When using the JIT on ARM, I get the following error message. The code works fine on both X86 32 and 64 bit architectures.

rbx: /home/dirkjan/llvm-3.3.src/include/llvm/CodeGen/MachineOperand.h:260: unsigned int llvm::MachineOperand::getReg() const: Assertion `isReg() && "This is not a register operand!"' failed.

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x74fff460 (LWP 652)]
__libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S:47
47 ../ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S: No such file or directory.
(gdb) bt 20
#0 __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S:47
#1 0x76d89e92 in __GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#2 0x76d8c26c in __GI_abort () at abort.c:91
#3 0x76d85344 in __assert_fail_base (fmt=0x76e2d8c8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
    assertion=0xb2bc84 "isReg() && \"This is not a register operand!\"", file=0x76e4608c "", line=260,
    function=0xb40964 "unsigned int llvm::MachineOperand::getReg() const") at assert.c:94
#4 0x76d853ca in __GI___assert_fail (assertion=0xb2bc84 "isReg() && \"This is not a register operand!\"", file=0x76e4608c "", line=2,
    function=0x74fff460 "\001") at assert.c:103
#5 0x00151c62 in llvm::MachineOperand::getReg (this=<optimized out>)
    at /home/dirkjan/llvm-3.3.src/include/llvm/CodeGen/MachineOperand.h:260
#6 0x003d8998 in getReg (this=<optimized out>) at /home/dirkjan/llvm-3.3.src/include/llvm/CodeGen/MachineOperand.h:260
#7 (anonymous namespace)::ARMCodeEmitter::emitLoadStoreInstruction (this=0x74725b20, MI=..., ImplicitRd=3855757312, ImplicitRn=0)
    at ARMCodeEmitter.cpp:1171
#8 0x003dade2 in (anonymous namespace)::ARMCodeEmitter::emitInstruction (this=0x74725b20, MI=...) at ARMCodeEmitter.cpp:563
#9 0x003dc42e in (anonymous namespace)::ARMCodeEmitter::runOnMachineFunction (this=0x74725b20, MF=...) at ARMCodeEmitter.cpp:403
#10 0x00604c8a in llvm::MachineFunctionPass::runOnFunction (this=0x74725b20, F=...) at MachineFunctionPass.cpp:33
#11 0x00a0a7b6 in runOnFunction (F=..., this=0x7470cdc8) at PassManager.cpp:1530
#12 llvm::FPPassManager::runOnFunction (this=0x7470cdc8, F=...) at PassManager.cpp:1508
#13 0x00a0a86e in llvm::FunctionPassManagerImpl::run (this=0x7470cc38, F=...) at PassManager.cpp:1481
#14 0x00a0a9a8 in llvm::FunctionPassManager::run (this=0x74702ec8, F=...) at PassManager.cpp:1399
#15 0x005b613e in llvm::JIT::jitTheFunction (this=<optimized out>, F=<optimized out>, locked=...) at JIT.cpp:646
#16 0x005b6582 in llvm::JIT::runJITOnFunctionUnlocked (this=0x7470bf70, F=<optimized out>, locked=...) at JIT.cpp:625
#17 0x005b685a in llvm::JIT::runJITOnFunction (this=0x7470bf70, F=0x7472e648, MCI=<optimized out>) at JIT.cpp:616
#18 0x002e9d30 in rubinius::jit::Compiler::generate_function (this=0x74ffed58, indy=<optimized out>) at vm/llvm/jit_compiler.cpp:118
#19 0x002fd474 in rubinius::BackgroundCompilerThread::perform (this=0x12e0f18) at vm/llvm/state.cpp:346

I've tried looking for this error, but can't seem to find any more information on what the cause of this could be. Anyone in here who has any idea how to fix this and get it working? I can also get more debug information if that is needed to find the cause of this issue.

Hi Dirkjan,

I've tried looking for this error, but can't seem to find any more information on what the cause of this could be.

This looks like a backtrace from the legacy JIT. Unfortunately that's known to be broken on ARM and you should use the MCJIT instead (see tools/lli/lli.cpp for an example of how to enable it).

We're hoping to get rid of the old one soon, but there are one or two features that don't quite work there yet. Lazy compilation is the only one I know of, since we got multi-module support yesterday. But there may be more.

Cheers.

Tim.

Hi Tim,

That's too bad :(. Last time I checked the MCJIT couldn't do what we needed, but perhaps it's a good time to check again. Do you know if there are any porting tips / howto's somewhere that discuss possible issues / caveats?

Hi,

I've tried looking for this error, but can't seem to find any more

information on what the cause of this could be.

This looks like a backtrace from the legacy JIT. Unfortunately that's

known to be broken on ARM and you should use the MCJIT instead (see
tools/lli/lli.cpp for an example of how to enable it).

There is one thing that's non-obvious: just setting
EngineBuilder::setUseMCJIT(true) without having the MCJIT header included
will silently just end up using the old JIT, not complain you've asked it do
something it couldn't do.

Cheers,
Dave

Can MCJIT handle thread-local references? This was the feature keeping us on the old JIT. If it's expected to be working then I'll give it another try.

David

Doesn't look like it. That would need fairly detailed (per-target) handling in RuntimeDyldELF (& MachO). There are hundreds of those relocations, plus some fairly hairy descriptors to setup. Though I suppose you might be able to limit CodeGen to TLSGD to get something functional.

A fun project though.

Cheers.

Tim.

I recently added support for small code model with PIC on x86-64, which as I recall was the blocking issue there. I don't believe that combination works on ARM yet.

-Andy

Lazy compilation should also be helped by the new multiple module support. You can get an idea of how it works in the "Making MCJIT Lazy" section of this blog post: http://blog.llvm.org/2013/07/kaleidoscope-performance-with-mcjit.html

The multiple module support took a few of the ideas from that blog example and made them internal to MCJIT. So now, for instance, if you have a whole lot of small modules and ask for a function pointer from one of them MCJIT will figure out which ones it needs to compile to satisfy dependencies between modules.

MCJIT will always be module based, so it can't do function-level lazy compilation the way the old JIT did, but if the client constructs input modules carefully we can get pretty close to the same behavior.

The new changes also take a first step in addressing the memory consumption issues with MCJIT, but there's still more to be done in that regard.

-Andy